github.com/adoriasoft/tendermint@v0.34.0-dev1.0.20200722151356-96d84601a75a/evidence/pool_test.go (about)

     1  package evidence
     2  
     3  import (
     4  	"os"
     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  	dbm "github.com/tendermint/tm-db"
    13  
    14  	"github.com/tendermint/tendermint/crypto/tmhash"
    15  	"github.com/tendermint/tendermint/libs/bytes"
    16  	"github.com/tendermint/tendermint/libs/log"
    17  	tmrand "github.com/tendermint/tendermint/libs/rand"
    18  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
    19  	sm "github.com/tendermint/tendermint/state"
    20  	"github.com/tendermint/tendermint/store"
    21  	"github.com/tendermint/tendermint/types"
    22  	tmtime "github.com/tendermint/tendermint/types/time"
    23  )
    24  
    25  func TestMain(m *testing.M) {
    26  
    27  	code := m.Run()
    28  	os.Exit(code)
    29  }
    30  
    31  const evidenceChainID = "test_chain"
    32  
    33  func TestEvidencePool(t *testing.T) {
    34  	var (
    35  		val          = types.NewMockPV()
    36  		valAddr      = val.PrivKey.PubKey().Address()
    37  		height       = int64(52)
    38  		stateDB      = initializeValidatorState(val, height)
    39  		evidenceDB   = dbm.NewMemDB()
    40  		blockStoreDB = dbm.NewMemDB()
    41  		blockStore   = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), valAddr)
    42  		evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
    43  
    44  		goodEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(height, evidenceTime, val, evidenceChainID)
    45  		badEvidence  = types.NewMockDuplicateVoteEvidenceWithValidator(1, evidenceTime, val, evidenceChainID)
    46  	)
    47  
    48  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
    49  	require.NoError(t, err)
    50  
    51  	// bad evidence
    52  	err = pool.AddEvidence(badEvidence)
    53  	if assert.Error(t, err) {
    54  		assert.Contains(t, err.Error(), "is too old; min height is 32 and evidence can not be older than")
    55  	}
    56  	assert.False(t, pool.IsPending(badEvidence))
    57  	assert.True(t, pool.IsEvidenceExpired(badEvidence))
    58  
    59  	// good evidence
    60  	evAdded := make(chan struct{})
    61  	go func() {
    62  		<-pool.EvidenceWaitChan()
    63  		close(evAdded)
    64  	}()
    65  
    66  	err = pool.AddEvidence(goodEvidence)
    67  	require.NoError(t, err)
    68  
    69  	select {
    70  	case <-evAdded:
    71  	case <-time.After(5 * time.Second):
    72  		t.Fatal("evidence was not added to list after 5s")
    73  	}
    74  
    75  	assert.Equal(t, 1, pool.evidenceList.Len())
    76  
    77  	// if we send it again, it shouldnt add and return an error
    78  	err = pool.AddEvidence(goodEvidence)
    79  	assert.NoError(t, err)
    80  	assert.Equal(t, 1, pool.evidenceList.Len())
    81  }
    82  
    83  func TestProposingAndCommittingEvidence(t *testing.T) {
    84  	var (
    85  		val          = types.NewMockPV()
    86  		height       = int64(1)
    87  		stateDB      = initializeValidatorState(val, height)
    88  		evidenceDB   = dbm.NewMemDB()
    89  		blockStoreDB = dbm.NewMemDB()
    90  		blockStore   = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), val.PrivKey.PubKey().Address())
    91  		evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
    92  	)
    93  
    94  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
    95  	require.NoError(t, err)
    96  
    97  	// evidence not seen yet:
    98  	evidence := types.NewMockDuplicateVoteEvidenceWithValidator(height, evidenceTime, val, evidenceChainID)
    99  	assert.False(t, pool.IsCommitted(evidence))
   100  
   101  	// evidence seen but not yet committed:
   102  	assert.NoError(t, pool.AddEvidence(evidence))
   103  	assert.False(t, pool.IsCommitted(evidence))
   104  
   105  	// test evidence is proposed
   106  	proposedEvidence := pool.AllPendingEvidence()
   107  	assert.Equal(t, proposedEvidence[0], evidence)
   108  
   109  	// evidence seen and committed:
   110  	pool.MarkEvidenceAsCommitted(height, proposedEvidence)
   111  	assert.True(t, pool.IsCommitted(evidence))
   112  	assert.False(t, pool.IsPending(evidence))
   113  	assert.Equal(t, 0, pool.evidenceList.Len())
   114  
   115  	// evidence should
   116  }
   117  
   118  func TestAddEvidence(t *testing.T) {
   119  	var (
   120  		val          = types.NewMockPV()
   121  		valAddr      = val.PrivKey.PubKey().Address()
   122  		height       = int64(30)
   123  		stateDB      = initializeValidatorState(val, height)
   124  		evidenceDB   = dbm.NewMemDB()
   125  		blockStoreDB = dbm.NewMemDB()
   126  		blockStore   = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), valAddr)
   127  		evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
   128  	)
   129  
   130  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   131  	require.NoError(t, err)
   132  
   133  	testCases := []struct {
   134  		evHeight      int64
   135  		evTime        time.Time
   136  		expErr        bool
   137  		evDescription string
   138  	}{
   139  		{height, time.Now(), false, "valid evidence"},
   140  		{height, evidenceTime, false, "valid evidence (despite old time)"},
   141  		{int64(1), time.Now(), false, "valid evidence (despite old height)"},
   142  		{int64(1), evidenceTime, true,
   143  			"evidence from height 1 (created at: 2019-01-01 00:00:00 +0000 UTC) is too old"},
   144  	}
   145  
   146  	for _, tc := range testCases {
   147  		tc := tc
   148  		t.Run(tc.evDescription, func(t *testing.T) {
   149  			ev := types.NewMockDuplicateVoteEvidence(tc.evHeight, tc.evTime, evidenceChainID)
   150  			err := pool.AddEvidence(ev)
   151  			if tc.expErr {
   152  				assert.Error(t, err)
   153  				t.Log(err)
   154  			}
   155  		})
   156  	}
   157  }
   158  
   159  func TestEvidencePoolUpdate(t *testing.T) {
   160  	var (
   161  		val          = types.NewMockPV()
   162  		valAddr      = val.PrivKey.PubKey().Address()
   163  		height       = int64(21)
   164  		stateDB      = initializeValidatorState(val, height)
   165  		evidenceDB   = dbm.NewMemDB()
   166  		blockStoreDB = dbm.NewMemDB()
   167  		state        = sm.LoadState(stateDB)
   168  		blockStore   = initializeBlockStore(blockStoreDB, state, valAddr)
   169  	)
   170  
   171  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   172  	require.NoError(t, err)
   173  
   174  	// create new block (no need to save it to blockStore)
   175  	evidence := types.NewMockDuplicateVoteEvidence(height, time.Now(), evidenceChainID)
   176  	lastCommit := makeCommit(height, valAddr)
   177  	block := types.MakeBlock(height+1, []types.Tx{}, lastCommit, []types.Evidence{evidence})
   178  	// update state (partially)
   179  	state.LastBlockHeight = height + 1
   180  
   181  	pool.Update(block, state)
   182  
   183  	// a) Update marks evidence as committed
   184  	assert.True(t, pool.IsCommitted(evidence))
   185  	// b) Update updates valToLastHeight map
   186  	assert.Equal(t, height+1, pool.ValidatorLastHeight(valAddr))
   187  }
   188  
   189  func TestEvidencePoolNewPool(t *testing.T) {
   190  	var (
   191  		val          = types.NewMockPV()
   192  		valAddr      = val.PrivKey.PubKey().Address()
   193  		height       = int64(1)
   194  		stateDB      = initializeValidatorState(val, height)
   195  		evidenceDB   = dbm.NewMemDB()
   196  		blockStoreDB = dbm.NewMemDB()
   197  		state        = sm.LoadState(stateDB)
   198  		blockStore   = initializeBlockStore(blockStoreDB, state, valAddr)
   199  	)
   200  
   201  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   202  	require.NoError(t, err)
   203  
   204  	assert.Equal(t, height, pool.ValidatorLastHeight(valAddr))
   205  	assert.EqualValues(t, 0, pool.ValidatorLastHeight([]byte("non-existent-validator")))
   206  }
   207  
   208  func TestAddingAndPruningPOLC(t *testing.T) {
   209  	var (
   210  		val          = types.NewMockPV()
   211  		valAddr      = val.PrivKey.PubKey().Address()
   212  		stateDB      = initializeValidatorState(val, 1)
   213  		evidenceDB   = dbm.NewMemDB()
   214  		blockStoreDB = dbm.NewMemDB()
   215  		state        = sm.LoadState(stateDB)
   216  		blockStore   = initializeBlockStore(blockStoreDB, state, valAddr)
   217  		height       = state.ConsensusParams.Evidence.MaxAgeNumBlocks * 2
   218  		evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
   219  		firstBlockID = types.BlockID{
   220  			Hash: tmrand.Bytes(tmhash.Size),
   221  			PartSetHeader: types.PartSetHeader{
   222  				Total: 1,
   223  				Hash:  tmrand.Bytes(tmhash.Size),
   224  			},
   225  		}
   226  	)
   227  
   228  	voteA := makeVote(1, 1, 0, val.PrivKey.PubKey().Address(), firstBlockID, evidenceTime)
   229  	vA := voteA.ToProto()
   230  	err := val.SignVote(evidenceChainID, vA)
   231  	require.NoError(t, err)
   232  	voteA.Signature = vA.Signature
   233  
   234  	pubKey, _ := types.NewMockPV().GetPubKey()
   235  	polc := &types.ProofOfLockChange{
   236  		Votes:  []*types.Vote{voteA},
   237  		PubKey: pubKey,
   238  	}
   239  
   240  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   241  	require.NoError(t, err)
   242  
   243  	err = pool.AddPOLC(polc)
   244  	assert.NoError(t, err)
   245  
   246  	// should be able to retrieve polc
   247  	newPolc, err := pool.RetrievePOLC(1, 1)
   248  	assert.NoError(t, err)
   249  	assert.True(t, polc.Equal(newPolc))
   250  
   251  	// should not be able to retrieve because it doesn't exist
   252  	emptyPolc, err := pool.RetrievePOLC(2, 1)
   253  	assert.NoError(t, err)
   254  	assert.Nil(t, emptyPolc)
   255  
   256  	lastCommit := makeCommit(height-1, valAddr)
   257  	block := types.MakeBlock(height, []types.Tx{}, lastCommit, []types.Evidence{})
   258  	// update state (partially)
   259  	state.LastBlockHeight = height
   260  	pool.state.LastBlockHeight = height
   261  
   262  	// update should prune the polc
   263  	pool.Update(block, state)
   264  
   265  	emptyPolc, err = pool.RetrievePOLC(1, 1)
   266  	assert.NoError(t, err)
   267  	assert.Nil(t, emptyPolc)
   268  
   269  }
   270  
   271  func TestRecoverPendingEvidence(t *testing.T) {
   272  	var (
   273  		val             = types.NewMockPV()
   274  		valAddr         = val.PrivKey.PubKey().Address()
   275  		height          = int64(30)
   276  		stateDB         = initializeValidatorState(val, height)
   277  		evidenceDB      = dbm.NewMemDB()
   278  		blockStoreDB    = dbm.NewMemDB()
   279  		state           = sm.LoadState(stateDB)
   280  		blockStore      = initializeBlockStore(blockStoreDB, state, valAddr)
   281  		evidenceTime    = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
   282  		goodEvidence    = types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(), val, evidenceChainID)
   283  		expiredEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(int64(1), evidenceTime, val, evidenceChainID)
   284  	)
   285  
   286  	// load good evidence
   287  	goodKey := keyPending(goodEvidence)
   288  	evi, err := types.EvidenceToProto(goodEvidence)
   289  	require.NoError(t, err)
   290  	goodEvidenceBytes, err := proto.Marshal(evi)
   291  	require.NoError(t, err)
   292  	_ = evidenceDB.Set(goodKey, goodEvidenceBytes)
   293  
   294  	// load expired evidence
   295  	expiredKey := keyPending(expiredEvidence)
   296  	eevi, err := types.EvidenceToProto(expiredEvidence)
   297  	require.NoError(t, err)
   298  
   299  	expiredEvidenceBytes, err := proto.Marshal(eevi)
   300  	require.NoError(t, err)
   301  
   302  	_ = evidenceDB.Set(expiredKey, expiredEvidenceBytes)
   303  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   304  	require.NoError(t, err)
   305  	assert.Equal(t, 1, pool.evidenceList.Len())
   306  	assert.True(t, pool.IsPending(goodEvidence))
   307  }
   308  
   309  // Comprehensive set of test cases relating to the adding, upgrading and overall
   310  // processing of PotentialAmnesiaEvidence and AmnesiaEvidence
   311  func TestAddingPotentialAmnesiaEvidence(t *testing.T) {
   312  	var (
   313  		val     = types.NewMockPV()
   314  		val2    = types.NewMockPV()
   315  		pubKey  = val.PrivKey.PubKey()
   316  		pubKey2 = val2.PrivKey.PubKey()
   317  		valSet  = &types.ValidatorSet{
   318  			Validators: []*types.Validator{
   319  				val.ExtractIntoValidator(1),
   320  				val2.ExtractIntoValidator(3),
   321  			},
   322  			Proposer: val.ExtractIntoValidator(1),
   323  		}
   324  		height       = int64(30)
   325  		stateDB      = initializeStateFromValidatorSet(valSet, height)
   326  		evidenceDB   = dbm.NewMemDB()
   327  		blockStoreDB = dbm.NewMemDB()
   328  		state        = sm.LoadState(stateDB)
   329  		blockStore   = initializeBlockStore(blockStoreDB, state, pubKey.Address())
   330  		//evidenceTime    = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
   331  		firstBlockID = types.BlockID{
   332  			Hash: []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
   333  			PartSetHeader: types.PartSetHeader{
   334  				Total: 1,
   335  				Hash:  []byte("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
   336  			},
   337  		}
   338  		secondBlockID = types.BlockID{
   339  			Hash: []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
   340  			PartSetHeader: types.PartSetHeader{
   341  				Total: 1,
   342  				Hash:  []byte("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
   343  			},
   344  		}
   345  		evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
   346  	)
   347  
   348  	// TEST SETUP
   349  	pool, err := NewPool(stateDB, evidenceDB, blockStore)
   350  	require.NoError(t, err)
   351  
   352  	pool.SetLogger(log.TestingLogger())
   353  
   354  	voteA := makeVote(height, 0, 0, pubKey.Address(), firstBlockID, evidenceTime)
   355  	vA := voteA.ToProto()
   356  	err = val.SignVote(evidenceChainID, vA)
   357  	voteA.Signature = vA.Signature
   358  	require.NoError(t, err)
   359  	voteB := makeVote(height, 1, 0, pubKey.Address(), secondBlockID, evidenceTime.Add(3*time.Second))
   360  	vB := voteB.ToProto()
   361  	err = val.SignVote(evidenceChainID, vB)
   362  	voteB.Signature = vB.Signature
   363  	require.NoError(t, err)
   364  	voteC := makeVote(height, 2, 0, pubKey.Address(), firstBlockID, evidenceTime.Add(2*time.Second))
   365  	vC := voteC.ToProto()
   366  	err = val.SignVote(evidenceChainID, vC)
   367  	voteC.Signature = vC.Signature
   368  	require.NoError(t, err)
   369  	ev := &types.PotentialAmnesiaEvidence{
   370  		VoteA: voteA,
   371  		VoteB: voteB,
   372  	}
   373  
   374  	polc := &types.ProofOfLockChange{
   375  		Votes:  []*types.Vote{voteB},
   376  		PubKey: pubKey2,
   377  	}
   378  	err = pool.AddPOLC(polc)
   379  	require.NoError(t, err)
   380  
   381  	polc, err = pool.RetrievePOLC(height, 1)
   382  	require.NoError(t, err)
   383  	require.NotEmpty(t, polc)
   384  
   385  	secondValVote := makeVote(height, 1, 0, pubKey2.Address(), secondBlockID, evidenceTime.Add(1*time.Second))
   386  	vv2 := secondValVote.ToProto()
   387  	err = val2.SignVote(evidenceChainID, vv2)
   388  	require.NoError(t, err)
   389  	secondValVote.Signature = vv2.Signature
   390  
   391  	validPolc := &types.ProofOfLockChange{
   392  		Votes:  []*types.Vote{secondValVote},
   393  		PubKey: pubKey,
   394  	}
   395  
   396  	// CASE A
   397  	pool.logger.Info("CASE A")
   398  	// we expect the evidence pool to find the polc but log an error as the polc is not valid -> vote was
   399  	// not from a validator in this set. However, an error isn't thrown because the evidence pool
   400  	// should still be able to save the regular potential amnesia evidence.
   401  	err = pool.AddEvidence(ev)
   402  	assert.NoError(t, err)
   403  
   404  	// evidence requires trial period until it is available -> we expect no evidence to be returned
   405  	assert.Equal(t, 0, len(pool.PendingEvidence(1)))
   406  	assert.True(t, pool.IsOnTrial(ev))
   407  
   408  	nextHeight := pool.nextEvidenceTrialEndedHeight
   409  	assert.Greater(t, nextHeight, int64(0))
   410  
   411  	// CASE B
   412  	pool.logger.Info("CASE B")
   413  	// evidence is not ready to be upgraded so we return the height we expect the evidence to be.
   414  	nextHeight = pool.upgradePotentialAmnesiaEvidence()
   415  	assert.Equal(t, height+pool.state.ConsensusParams.Evidence.ProofTrialPeriod, nextHeight)
   416  
   417  	// CASE C
   418  	pool.logger.Info("CASE C")
   419  	// now evidence is ready to be upgraded to amnesia evidence -> we expect -1 to be the next height as their is
   420  	// no more pending potential amnesia evidence left
   421  	lastCommit := makeCommit(height+1, pubKey.Address())
   422  	block := types.MakeBlock(height+2, []types.Tx{}, lastCommit, []types.Evidence{})
   423  	state.LastBlockHeight = height + 2
   424  
   425  	pool.Update(block, state)
   426  	assert.Equal(t, int64(-1), pool.nextEvidenceTrialEndedHeight)
   427  
   428  	assert.Equal(t, 1, len(pool.PendingEvidence(1)))
   429  
   430  	// CASE D
   431  	pool.logger.Info("CASE D")
   432  	// evidence of voting back in the past which is instantly punishable -> amnesia evidence is made directly
   433  	ev2 := &types.PotentialAmnesiaEvidence{
   434  		VoteA: voteC,
   435  		VoteB: voteB,
   436  	}
   437  	err = pool.AddEvidence(ev2)
   438  	assert.NoError(t, err)
   439  	expectedAe := &types.AmnesiaEvidence{
   440  		PotentialAmnesiaEvidence: ev2,
   441  		Polc:                     types.NewEmptyPOLC(),
   442  	}
   443  
   444  	assert.True(t, pool.IsPending(expectedAe))
   445  	assert.Equal(t, 2, len(pool.AllPendingEvidence()))
   446  
   447  	// CASE E
   448  	pool.logger.Info("CASE E")
   449  	// test for receiving amnesia evidence
   450  	ae := types.NewAmnesiaEvidence(ev, types.NewEmptyPOLC())
   451  	// we need to run the trial period ourselves so amnesia evidence should not be added, instead
   452  	// we should extract out the potential amnesia evidence and trying to add that before realising
   453  	// that we already have it -> no error
   454  	err = pool.AddEvidence(ae)
   455  	assert.NoError(t, err)
   456  	assert.Equal(t, 2, len(pool.AllPendingEvidence()))
   457  
   458  	voteD := makeVote(height, 2, 0, pubKey.Address(), firstBlockID, evidenceTime.Add(4*time.Second))
   459  	vD := voteD.ToProto()
   460  	err = val.SignVote(evidenceChainID, vD)
   461  	require.NoError(t, err)
   462  	voteD.Signature = vD.Signature
   463  
   464  	// CASE F
   465  	pool.logger.Info("CASE F")
   466  	// a new amnesia evidence is seen. It has an empty polc so we should extract the potential amnesia evidence
   467  	// and start our own trial
   468  	newPe := &types.PotentialAmnesiaEvidence{
   469  		VoteA: voteB,
   470  		VoteB: voteD,
   471  	}
   472  	newAe := &types.AmnesiaEvidence{
   473  		PotentialAmnesiaEvidence: newPe,
   474  		Polc:                     types.NewEmptyPOLC(),
   475  	}
   476  	err = pool.AddEvidence(newAe)
   477  	assert.NoError(t, err)
   478  	assert.Equal(t, 2, len(pool.AllPendingEvidence()))
   479  	assert.True(t, pool.IsOnTrial(newPe))
   480  
   481  	// CASE G
   482  	pool.logger.Info("CASE G")
   483  	// Finally, we receive an amnesia evidence containing a valid polc for an earlier potential amnesia evidence
   484  	// that we have already upgraded to. We should ad this new amnesia evidence in replace of the prior
   485  	// amnesia evidence with an empty polc that we have
   486  	aeWithPolc := &types.AmnesiaEvidence{
   487  		PotentialAmnesiaEvidence: ev,
   488  		Polc:                     validPolc,
   489  	}
   490  	err = pool.AddEvidence(aeWithPolc)
   491  	assert.NoError(t, err)
   492  	assert.True(t, pool.IsPending(aeWithPolc))
   493  	assert.Equal(t, 2, len(pool.AllPendingEvidence()))
   494  	t.Log(pool.AllPendingEvidence())
   495  
   496  }
   497  
   498  func initializeStateFromValidatorSet(valSet *types.ValidatorSet, height int64) dbm.DB {
   499  	stateDB := dbm.NewMemDB()
   500  	state := sm.State{
   501  		ChainID:                     evidenceChainID,
   502  		LastBlockHeight:             height,
   503  		LastBlockTime:               tmtime.Now(),
   504  		Validators:                  valSet,
   505  		NextValidators:              valSet.CopyIncrementProposerPriority(1),
   506  		LastValidators:              valSet,
   507  		LastHeightValidatorsChanged: 1,
   508  		ConsensusParams: tmproto.ConsensusParams{
   509  			Block: tmproto.BlockParams{
   510  				MaxBytes: 22020096,
   511  				MaxGas:   -1,
   512  			},
   513  			Evidence: tmproto.EvidenceParams{
   514  				MaxAgeNumBlocks:  20,
   515  				MaxAgeDuration:   48 * time.Hour,
   516  				MaxNum:           50,
   517  				ProofTrialPeriod: 1,
   518  			},
   519  		},
   520  	}
   521  
   522  	// save all states up to height
   523  	for i := int64(0); i <= height; i++ {
   524  		state.LastBlockHeight = i
   525  		sm.SaveState(stateDB, state)
   526  	}
   527  
   528  	return stateDB
   529  }
   530  
   531  func initializeValidatorState(privVal types.PrivValidator, height int64) dbm.DB {
   532  
   533  	pubKey, _ := privVal.GetPubKey()
   534  	validator := &types.Validator{Address: pubKey.Address(), VotingPower: 0, PubKey: pubKey}
   535  
   536  	// create validator set and state
   537  	valSet := &types.ValidatorSet{
   538  		Validators: []*types.Validator{validator},
   539  		Proposer:   validator,
   540  	}
   541  
   542  	return initializeStateFromValidatorSet(valSet, height)
   543  }
   544  
   545  // initializeBlockStore creates a block storage and populates it w/ a dummy
   546  // block at +height+.
   547  func initializeBlockStore(db dbm.DB, state sm.State, valAddr []byte) *store.BlockStore {
   548  	blockStore := store.NewBlockStore(db)
   549  
   550  	for i := int64(1); i <= state.LastBlockHeight; i++ {
   551  		lastCommit := makeCommit(i-1, valAddr)
   552  		block, _ := state.MakeBlock(i, []types.Tx{}, lastCommit, nil,
   553  			state.Validators.GetProposer().Address)
   554  
   555  		const parts = 1
   556  		partSet := block.MakePartSet(parts)
   557  
   558  		seenCommit := makeCommit(i, valAddr)
   559  		blockStore.SaveBlock(block, partSet, seenCommit)
   560  	}
   561  
   562  	return blockStore
   563  }
   564  
   565  func makeCommit(height int64, valAddr []byte) *types.Commit {
   566  	commitSigs := []types.CommitSig{{
   567  		BlockIDFlag:      types.BlockIDFlagCommit,
   568  		ValidatorAddress: valAddr,
   569  		Timestamp:        time.Now(),
   570  		Signature:        []byte("Signature"),
   571  	}}
   572  	return types.NewCommit(height, 0, types.BlockID{}, commitSigs)
   573  }
   574  
   575  func makeVote(height int64, round, index int32, addr bytes.HexBytes,
   576  	blockID types.BlockID, time time.Time) *types.Vote {
   577  	return &types.Vote{
   578  		Type:             tmproto.SignedMsgType(2),
   579  		Height:           height,
   580  		Round:            round,
   581  		BlockID:          blockID,
   582  		Timestamp:        time,
   583  		ValidatorAddress: addr,
   584  		ValidatorIndex:   index,
   585  	}
   586  }