diff --git a/blockchain/v0/reactor_test.go b/blockchain/v0/reactor_test.go index ffce2b3cc..a6ff8847d 100644 --- a/blockchain/v0/reactor_test.go +++ b/blockchain/v0/reactor_test.go @@ -9,6 +9,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/mempool/mock" "github.com/tendermint/tendermint/p2p" @@ -123,12 +124,11 @@ func (rts *reactorTestSuite) addNode(t *testing.T, lastBlockMeta := blockStore.LoadBlockMeta(blockHeight - 1) lastBlock := blockStore.LoadBlock(blockHeight - 1) - vote, err := types.MakeVote( - lastBlock.Header.Height, - lastBlockMeta.BlockID, - state.Validators, + vote, err := factory.MakeVote( privVal, - lastBlock.Header.ChainID, + lastBlock.Header.ChainID, 0, + lastBlock.Header.Height, 0, 2, + lastBlockMeta.BlockID, time.Now(), ) require.NoError(t, err) @@ -182,7 +182,7 @@ func TestReactor_AbruptDisconnect(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) - genDoc, privVals := randGenesisDoc(config, 1, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, 1, false, 30) maxBlockHeight := int64(64) rts := setup(t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0) @@ -217,7 +217,7 @@ func TestReactor_NoBlockResponse(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_test") defer os.RemoveAll(config.RootDir) - genDoc, privVals := randGenesisDoc(config, 1, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, 1, false, 30) maxBlockHeight := int64(65) rts := setup(t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0) @@ -265,7 +265,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) { defer os.RemoveAll(config.RootDir) maxBlockHeight := int64(48) - genDoc, privVals := randGenesisDoc(config, 1, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, 1, false, 30) rts := setup(t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0}, 1000) @@ -299,7 +299,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) { // // XXX: This causes a potential race condition. // See: https://github.com/tendermint/tendermint/issues/6005 - otherGenDoc, otherPrivVals := randGenesisDoc(config, 1, false, 30) + otherGenDoc, otherPrivVals := factory.RandGenesisDoc(config, 1, false, 30) newNode := rts.network.MakeNode(t, p2ptest.NodeOptions{ MaxPeers: uint16(len(rts.nodes) + 1), MaxConnected: uint16(len(rts.nodes) + 1), diff --git a/blockchain/v0/test_util.go b/blockchain/v0/test_util.go index f9b119d14..a36934366 100644 --- a/blockchain/v0/test_util.go +++ b/blockchain/v0/test_util.go @@ -1,42 +1,10 @@ package v0 import ( - "sort" - - cfg "github.com/tendermint/tendermint/config" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" ) -func randGenesisDoc( - config *cfg.Config, - numValidators int, - randPower bool, - minPower int64, -) (*types.GenesisDoc, []types.PrivValidator) { - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]types.PrivValidator, numValidators) - - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Power: val.VotingPower, - } - - privValidators[i] = privVal - } - - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - - return &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - ChainID: config.ChainID(), - Validators: validators, - }, privValidators -} - func makeTxs(height int64) (txs []types.Tx) { for i := 0; i < 10; i++ { txs = append(txs, types.Tx([]byte{byte(height), byte(i)})) diff --git a/blockchain/v2/reactor_test.go b/blockchain/v2/reactor_test.go index 78a99a9f8..477b09f45 100644 --- a/blockchain/v2/reactor_test.go +++ b/blockchain/v2/reactor_test.go @@ -4,7 +4,6 @@ import ( "fmt" "net" "os" - "sort" "sync" "testing" "time" @@ -17,6 +16,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/blockchain/v2/internal/behavior" cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/service" "github.com/tendermint/tendermint/mempool/mock" @@ -27,7 +27,6 @@ import ( sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/store" "github.com/tendermint/tendermint/types" - tmtime "github.com/tendermint/tendermint/types/time" ) type mockPeer struct { @@ -366,7 +365,7 @@ func TestReactorHelperMode(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_v2_test") defer os.RemoveAll(config.RootDir) - genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, 1, false, 30) params := testReactorParams{ logger: log.TestingLogger(), @@ -456,7 +455,7 @@ func TestReactorHelperMode(t *testing.T) { func TestReactorSetSwitchNil(t *testing.T) { config := cfg.ResetTestRoot("blockchain_reactor_v2_test") defer os.RemoveAll(config.RootDir) - genDoc, privVals := randGenesisDoc(config.ChainID(), 1, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, 1, false, 30) reactor := newTestReactor(testReactorParams{ logger: log.TestingLogger(), @@ -488,27 +487,6 @@ type testApp struct { abci.BaseApplication } -func randGenesisDoc(chainID string, numValidators int, randPower bool, minPower int64) ( - *types.GenesisDoc, []types.PrivValidator) { - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Power: val.VotingPower, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - - return &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - ChainID: chainID, - Validators: validators, - }, privValidators -} - // Why are we importing the entire blockExecutor dependency graph here // when we have the facilities to func newReactorStore( @@ -548,12 +526,11 @@ func newReactorStore( if blockHeight > 1 { lastBlockMeta := blockStore.LoadBlockMeta(blockHeight - 1) lastBlock := blockStore.LoadBlock(blockHeight - 1) - vote, err := types.MakeVote( - lastBlock.Header.Height, - lastBlockMeta.BlockID, - state.Validators, + vote, err := factory.MakeVote( privVals[0], - lastBlock.Header.ChainID, + lastBlock.Header.ChainID, 0, + lastBlock.Header.Height, 0, 2, + lastBlockMeta.BlockID, time.Now(), ) if err != nil { diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 4e10b30b0..1aa1d6a43 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -13,6 +13,7 @@ import ( abcicli "github.com/tendermint/tendermint/abci/client" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/evidence" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmsync "github.com/tendermint/tendermint/libs/sync" mempl "github.com/tendermint/tendermint/mempool" @@ -36,7 +37,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { tickerFunc := newMockTickerFunc(true) appFunc := newCounter - genDoc, privVals := randGenesisDoc(config, nValidators, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, nValidators, false, 30) states := make([]*State, nValidators) for i := 0; i < nValidators; i++ { diff --git a/consensus/common_test.go b/consensus/common_test.go index c763cafc6..e0aac0695 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -8,7 +8,6 @@ import ( "io/ioutil" "os" "path/filepath" - "sort" "sync" "testing" "time" @@ -26,6 +25,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" cfg "github.com/tendermint/tendermint/config" cstypes "github.com/tendermint/tendermint/consensus/types" + "github.com/tendermint/tendermint/internal/test/factory" tmbytes "github.com/tendermint/tendermint/libs/bytes" "github.com/tendermint/tendermint/libs/log" tmos "github.com/tendermint/tendermint/libs/os" @@ -709,7 +709,7 @@ func randConsensusState( configOpts ...func(*cfg.Config), ) ([]*State, cleanupFunc) { - genDoc, privVals := randGenesisDoc(config, nValidators, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, nValidators, false, 30) css := make([]*State, nValidators) logger := consensusLogger() @@ -763,7 +763,7 @@ func randConsensusNetWithPeers( tickerFunc func() TimeoutTicker, appFunc func(string) abci.Application, ) ([]*State, *types.GenesisDoc, *cfg.Config, cleanupFunc) { - genDoc, privVals := randGenesisDoc(config, nValidators, false, testMinPower) + genDoc, privVals := factory.RandGenesisDoc(config, nValidators, false, testMinPower) css := make([]*State, nPeers) logger := consensusLogger() @@ -818,39 +818,13 @@ func randConsensusNetWithPeers( } } -func randGenesisDoc( - config *cfg.Config, - numValidators int, - randPower bool, - minPower int64) (*types.GenesisDoc, []types.PrivValidator) { - - validators := make([]types.GenesisValidator, numValidators) - privValidators := make([]types.PrivValidator, numValidators) - for i := 0; i < numValidators; i++ { - val, privVal := types.RandValidator(randPower, minPower) - validators[i] = types.GenesisValidator{ - PubKey: val.PubKey, - Power: val.VotingPower, - } - privValidators[i] = privVal - } - sort.Sort(types.PrivValidatorsByAddress(privValidators)) - - return &types.GenesisDoc{ - GenesisTime: tmtime.Now(), - InitialHeight: 1, - ChainID: config.ChainID(), - Validators: validators, - }, privValidators -} - func randGenesisState( config *cfg.Config, numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) { - genDoc, privValidators := randGenesisDoc(config, numValidators, randPower, minPower) + genDoc, privValidators := factory.RandGenesisDoc(config, numValidators, randPower, minPower) s0, _ := sm.MakeGenesisState(genDoc) return s0, privValidators } diff --git a/consensus/msgs_test.go b/consensus/msgs_test.go index 24c56d4a7..953a6355d 100644 --- a/consensus/msgs_test.go +++ b/consensus/msgs_test.go @@ -1,7 +1,6 @@ package consensus import ( - "context" "encoding/hex" "fmt" "math" @@ -15,6 +14,7 @@ import ( cstypes "github.com/tendermint/tendermint/consensus/types" "github.com/tendermint/tendermint/crypto/merkle" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/bits" "github.com/tendermint/tendermint/libs/bytes" tmrand "github.com/tendermint/tendermint/libs/rand" @@ -63,13 +63,8 @@ func TestMsgToProto(t *testing.T) { pbProposal := proposal.ToProto() pv := types.NewMockPV() - pk, err := pv.GetPubKey(context.Background()) - require.NoError(t, err) - val := types.NewValidator(pk, 100) - - vote, err := types.MakeVote( - 1, types.BlockID{}, &types.ValidatorSet{Proposer: val, Validators: []*types.Validator{val}}, - pv, "chainID", time.Now()) + vote, err := factory.MakeVote(pv, factory.DefaultTestChainID, + 0, 1, 0, 2, types.BlockID{}, time.Now()) require.NoError(t, err) pbVote := vote.ToProto() diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index e09ddc953..6e2c43df8 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -18,6 +18,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" cfg "github.com/tendermint/tendermint/config" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmsync "github.com/tendermint/tendermint/libs/sync" mempl "github.com/tendermint/tendermint/mempool" @@ -281,7 +282,7 @@ func TestReactorWithEvidence(t *testing.T) { tickerFunc := newMockTickerFunc(true) appFunc := newCounter - genDoc, privVals := randGenesisDoc(config, n, false, 30) + genDoc, privVals := factory.RandGenesisDoc(config, n, false, 30) states := make([]*State, n) logger := consensusLogger() diff --git a/consensus/replay_test.go b/consensus/replay_test.go index e51fe1217..ec328730c 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -24,6 +24,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmrand "github.com/tendermint/tendermint/libs/rand" mempl "github.com/tendermint/tendermint/mempool" @@ -1023,12 +1024,11 @@ func makeBlock(state sm.State, lastBlock *types.Block, lastBlockMeta *types.Bloc lastCommit := types.NewCommit(height-1, 0, types.BlockID{}, nil) if height > 1 { - vote, _ := types.MakeVote( - lastBlock.Header.Height, - lastBlockMeta.BlockID, - state.Validators, + vote, _ := factory.MakeVote( privVal, lastBlock.Header.ChainID, + 1, lastBlock.Header.Height, 0, 2, + lastBlockMeta.BlockID, time.Now()) lastCommit = types.NewCommit(vote.Height, vote.Round, lastBlockMeta.BlockID, []types.CommitSig{vote.CommitSig()}) @@ -1258,7 +1258,7 @@ func (bs *mockBlockStore) PruneBlocks(height int64) (uint64, error) { // Test handshake/init chain func TestHandshakeUpdatesValidators(t *testing.T) { - val, _ := types.RandValidator(true, 10) + val, _ := factory.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val}) app := &initChainApp{vals: types.TM2PB.ValidatorUpdates(vals)} clientCreator := proxy.NewLocalClientCreator(app) diff --git a/consensus/types/height_vote_set_test.go b/consensus/types/height_vote_set_test.go index e611c3981..3830b2d80 100644 --- a/consensus/types/height_vote_set_test.go +++ b/consensus/types/height_vote_set_test.go @@ -8,6 +8,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" "github.com/tendermint/tendermint/types" @@ -24,7 +25,7 @@ func TestMain(m *testing.M) { } func TestPeerCatchupRounds(t *testing.T) { - valSet, privVals := types.RandValidatorSet(10, 1) + valSet, privVals := factory.RandValidatorSet(10, 1) hvs := NewHeightVoteSet(config.ChainID(), 1, valSet) diff --git a/evidence/pool_test.go b/evidence/pool_test.go index dabda6578..251585c39 100644 --- a/evidence/pool_test.go +++ b/evidence/pool_test.go @@ -13,6 +13,7 @@ import ( "github.com/tendermint/tendermint/evidence" "github.com/tendermint/tendermint/evidence/mocks" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" sm "github.com/tendermint/tendermint/state" smmocks "github.com/tendermint/tendermint/state/mocks" @@ -36,7 +37,7 @@ func TestEvidencePoolBasic(t *testing.T) { blockStore = &mocks.BlockStore{} ) - valSet, privVals := types.RandValidatorSet(1, 10) + valSet, privVals := factory.RandValidatorSet(1, 10) blockStore.On("LoadBlockMeta", mock.AnythingOfType("int64")).Return( &types.BlockMeta{Header: types.Header{Time: defaultEvidenceTime}}, diff --git a/evidence/verify_test.go b/evidence/verify_test.go index e9bd43e25..880088b5c 100644 --- a/evidence/verify_test.go +++ b/evidence/verify_test.go @@ -15,12 +15,12 @@ import ( "github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/evidence" "github.com/tendermint/tendermint/evidence/mocks" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" sm "github.com/tendermint/tendermint/state" smmocks "github.com/tendermint/tendermint/state/mocks" "github.com/tendermint/tendermint/types" - "github.com/tendermint/tendermint/version" ) const ( @@ -190,23 +190,30 @@ func TestVerify_ForwardLunaticAttack(t *testing.T) { } func TestVerifyLightClientAttack_Equivocation(t *testing.T) { - conflictingVals, conflictingPrivVals := types.RandValidatorSet(5, 10) - trustedHeader := makeHeaderRandom(10) + conflictingVals, conflictingPrivVals := factory.RandValidatorSet(5, 10) - conflictingHeader := makeHeaderRandom(10) - conflictingHeader.ValidatorsHash = conflictingVals.Hash() + conflictingHeader, err := factory.MakeHeader(&types.Header{ + Height: 10, + Time: defaultEvidenceTime, + ValidatorsHash: conflictingVals.Hash(), + }) + require.NoError(t, err) - trustedHeader.ValidatorsHash = conflictingHeader.ValidatorsHash - trustedHeader.NextValidatorsHash = conflictingHeader.NextValidatorsHash - trustedHeader.ConsensusHash = conflictingHeader.ConsensusHash - trustedHeader.AppHash = conflictingHeader.AppHash - trustedHeader.LastResultsHash = conflictingHeader.LastResultsHash + trustedHeader, _ := factory.MakeHeader(&types.Header{ + Height: 10, + Time: defaultEvidenceTime, + ValidatorsHash: conflictingHeader.ValidatorsHash, + NextValidatorsHash: conflictingHeader.NextValidatorsHash, + ConsensusHash: conflictingHeader.ConsensusHash, + AppHash: conflictingHeader.AppHash, + LastResultsHash: conflictingHeader.LastResultsHash, + }) // we are simulating a duplicate vote attack where all the validators in the conflictingVals set // except the last validator vote twice - blockID := makeBlockID(conflictingHeader.Hash(), 1000, []byte("partshash")) + blockID := factory.MakeBlockIDWithHash(conflictingHeader.Hash()) voteSet := types.NewVoteSet(evidenceChainID, 10, 1, tmproto.SignedMsgType(2), conflictingVals) - commit, err := types.MakeCommit(blockID, 10, 1, voteSet, conflictingPrivVals[:4], defaultEvidenceTime) + commit, err := factory.MakeCommit(blockID, 10, 1, voteSet, conflictingPrivVals[:4], defaultEvidenceTime) require.NoError(t, err) ev := &types.LightClientAttackEvidence{ ConflictingBlock: &types.LightBlock{ @@ -224,7 +231,8 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) { trustedBlockID := makeBlockID(trustedHeader.Hash(), 1000, []byte("partshash")) trustedVoteSet := types.NewVoteSet(evidenceChainID, 10, 1, tmproto.SignedMsgType(2), conflictingVals) - trustedCommit, err := types.MakeCommit(trustedBlockID, 10, 1, trustedVoteSet, conflictingPrivVals, defaultEvidenceTime) + trustedCommit, err := factory.MakeCommit(trustedBlockID, 10, 1, + trustedVoteSet, conflictingPrivVals, defaultEvidenceTime) require.NoError(t, err) trustedSignedHeader := &types.SignedHeader{ Header: trustedHeader, @@ -274,22 +282,31 @@ func TestVerifyLightClientAttack_Equivocation(t *testing.T) { } func TestVerifyLightClientAttack_Amnesia(t *testing.T) { - conflictingVals, conflictingPrivVals := types.RandValidatorSet(5, 10) + var height int64 = 10 + conflictingVals, conflictingPrivVals := factory.RandValidatorSet(5, 10) + + conflictingHeader, err := factory.MakeHeader(&types.Header{ + Height: height, + Time: defaultEvidenceTime, + ValidatorsHash: conflictingVals.Hash(), + }) + require.NoError(t, err) - conflictingHeader := makeHeaderRandom(10) - conflictingHeader.ValidatorsHash = conflictingVals.Hash() - trustedHeader := makeHeaderRandom(10) - trustedHeader.ValidatorsHash = conflictingHeader.ValidatorsHash - trustedHeader.NextValidatorsHash = conflictingHeader.NextValidatorsHash - trustedHeader.AppHash = conflictingHeader.AppHash - trustedHeader.ConsensusHash = conflictingHeader.ConsensusHash - trustedHeader.LastResultsHash = conflictingHeader.LastResultsHash + trustedHeader, _ := factory.MakeHeader(&types.Header{ + Height: height, + Time: defaultEvidenceTime, + ValidatorsHash: conflictingHeader.ValidatorsHash, + NextValidatorsHash: conflictingHeader.NextValidatorsHash, + ConsensusHash: conflictingHeader.ConsensusHash, + AppHash: conflictingHeader.AppHash, + LastResultsHash: conflictingHeader.LastResultsHash, + }) // we are simulating an amnesia attack where all the validators in the conflictingVals set // except the last validator vote twice. However this time the commits are of different rounds. blockID := makeBlockID(conflictingHeader.Hash(), 1000, []byte("partshash")) - voteSet := types.NewVoteSet(evidenceChainID, 10, 0, tmproto.SignedMsgType(2), conflictingVals) - commit, err := types.MakeCommit(blockID, 10, 0, voteSet, conflictingPrivVals, defaultEvidenceTime) + voteSet := types.NewVoteSet(evidenceChainID, height, 0, tmproto.SignedMsgType(2), conflictingVals) + commit, err := factory.MakeCommit(blockID, height, 0, voteSet, conflictingPrivVals, defaultEvidenceTime) require.NoError(t, err) ev := &types.LightClientAttackEvidence{ ConflictingBlock: &types.LightBlock{ @@ -299,15 +316,16 @@ func TestVerifyLightClientAttack_Amnesia(t *testing.T) { }, ValidatorSet: conflictingVals, }, - CommonHeight: 10, + CommonHeight: height, ByzantineValidators: nil, // with amnesia evidence no validators are submitted as abci evidence TotalVotingPower: 50, Timestamp: defaultEvidenceTime, } trustedBlockID := makeBlockID(trustedHeader.Hash(), 1000, []byte("partshash")) - trustedVoteSet := types.NewVoteSet(evidenceChainID, 10, 1, tmproto.SignedMsgType(2), conflictingVals) - trustedCommit, err := types.MakeCommit(trustedBlockID, 10, 1, trustedVoteSet, conflictingPrivVals, defaultEvidenceTime) + trustedVoteSet := types.NewVoteSet(evidenceChainID, height, 1, tmproto.SignedMsgType(2), conflictingVals) + trustedCommit, err := factory.MakeCommit(trustedBlockID, height, 1, + trustedVoteSet, conflictingPrivVals, defaultEvidenceTime) require.NoError(t, err) trustedSignedHeader := &types.SignedHeader{ Header: trustedHeader, @@ -452,14 +470,14 @@ func makeLunaticEvidence( totalVals, byzVals, phantomVals int, commonTime, attackTime time.Time, ) (ev *types.LightClientAttackEvidence, trusted *types.LightBlock, common *types.LightBlock) { - commonValSet, commonPrivVals := types.RandValidatorSet(totalVals, defaultVotingPower) + commonValSet, commonPrivVals := factory.RandValidatorSet(totalVals, defaultVotingPower) require.Greater(t, totalVals, byzVals) // extract out the subset of byzantine validators in the common validator set byzValSet, byzPrivVals := commonValSet.Validators[:byzVals], commonPrivVals[:byzVals] - phantomValSet, phantomPrivVals := types.RandValidatorSet(phantomVals, defaultVotingPower) + phantomValSet, phantomPrivVals := factory.RandValidatorSet(phantomVals, defaultVotingPower) conflictingVals := phantomValSet.Copy() require.NoError(t, conflictingVals.UpdateWithChangeSet(byzValSet)) @@ -467,17 +485,20 @@ func makeLunaticEvidence( conflictingPrivVals = orderPrivValsByValSet(t, conflictingVals, conflictingPrivVals) - commonHeader := makeHeaderRandom(commonHeight) + commonHeader := factory.MakeRandomHeader() + commonHeader.Height = commonHeight commonHeader.Time = commonTime - trustedHeader := makeHeaderRandom(height) + trustedHeader := factory.MakeRandomHeader() + trustedHeader.Height = height - conflictingHeader := makeHeaderRandom(height) + conflictingHeader := factory.MakeRandomHeader() + conflictingHeader.Height = height conflictingHeader.Time = attackTime conflictingHeader.ValidatorsHash = conflictingVals.Hash() - blockID := makeBlockID(conflictingHeader.Hash(), 1000, []byte("partshash")) + blockID := factory.MakeBlockIDWithHash(conflictingHeader.Hash()) voteSet := types.NewVoteSet(evidenceChainID, height, 1, tmproto.SignedMsgType(2), conflictingVals) - commit, err := types.MakeCommit(blockID, height, 1, voteSet, conflictingPrivVals, defaultEvidenceTime) + commit, err := factory.MakeCommit(blockID, height, 1, voteSet, conflictingPrivVals, defaultEvidenceTime) require.NoError(t, err) ev = &types.LightClientAttackEvidence{ ConflictingBlock: &types.LightBlock{ @@ -501,10 +522,10 @@ func makeLunaticEvidence( }, ValidatorSet: commonValSet, } - trustedBlockID := makeBlockID(trustedHeader.Hash(), 1000, []byte("partshash")) - trustedVals, privVals := types.RandValidatorSet(totalVals, defaultVotingPower) + trustedBlockID := factory.MakeBlockIDWithHash(trustedHeader.Hash()) + trustedVals, privVals := factory.RandValidatorSet(totalVals, defaultVotingPower) trustedVoteSet := types.NewVoteSet(evidenceChainID, height, 1, tmproto.SignedMsgType(2), trustedVals) - trustedCommit, err := types.MakeCommit(trustedBlockID, height, 1, trustedVoteSet, privVals, defaultEvidenceTime) + trustedCommit, err := factory.MakeCommit(trustedBlockID, height, 1, trustedVoteSet, privVals, defaultEvidenceTime) require.NoError(t, err) trusted = &types.LightBlock{ SignedHeader: &types.SignedHeader{ @@ -516,14 +537,6 @@ func makeLunaticEvidence( return ev, trusted, common } -// func makeEquivocationEvidence() *types.LightClientAttackEvidence { - -// } - -// func makeAmnesiaEvidence() *types.LightClientAttackEvidence { - -// } - func makeVote( t *testing.T, val types.PrivValidator, chainID string, valIndex int32, height int64, round int32, step int, blockID types.BlockID, time time.Time) *types.Vote { @@ -548,25 +561,6 @@ func makeVote( return v } -func makeHeaderRandom(height int64) *types.Header { - return &types.Header{ - Version: version.Consensus{Block: version.BlockProtocol, App: 1}, - ChainID: evidenceChainID, - Height: height, - Time: defaultEvidenceTime, - LastBlockID: makeBlockID([]byte("headerhash"), 1000, []byte("partshash")), - LastCommitHash: crypto.CRandBytes(tmhash.Size), - DataHash: crypto.CRandBytes(tmhash.Size), - ValidatorsHash: crypto.CRandBytes(tmhash.Size), - NextValidatorsHash: crypto.CRandBytes(tmhash.Size), - ConsensusHash: crypto.CRandBytes(tmhash.Size), - AppHash: crypto.CRandBytes(tmhash.Size), - LastResultsHash: crypto.CRandBytes(tmhash.Size), - EvidenceHash: crypto.CRandBytes(tmhash.Size), - ProposerAddress: crypto.CRandBytes(crypto.AddressSize), - } -} - func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.BlockID { var ( h = make([]byte, tmhash.Size) diff --git a/internal/test/factory/block.go b/internal/test/factory/block.go new file mode 100644 index 000000000..87203221f --- /dev/null +++ b/internal/test/factory/block.go @@ -0,0 +1,95 @@ +package factory + +import ( + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/types" + "github.com/tendermint/tendermint/version" +) + +const ( + DefaultTestChainID = "test-chain" +) + +func MakeVersion() version.Consensus { + return version.Consensus{ + Block: version.BlockProtocol, + App: 1, + } +} + +func RandomAddress() []byte { + return crypto.CRandBytes(crypto.AddressSize) +} + +func RandomHash() []byte { + return crypto.CRandBytes(tmhash.Size) +} + +func MakeBlockID() types.BlockID { + return MakeBlockIDWithHash(RandomHash()) +} + +func MakeBlockIDWithHash(hash []byte) types.BlockID { + return types.BlockID{ + Hash: hash, + PartSetHeader: types.PartSetHeader{ + Total: 100, + Hash: RandomHash(), + }, + } +} + +// MakeHeader fills the rest of the contents of the header such that it passes +// validate basic +func MakeHeader(h *types.Header) (*types.Header, error) { + if h.Version.Block == 0 { + h.Version.Block = version.BlockProtocol + } + if h.Height == 0 { + h.Height = 1 + } + if h.LastBlockID.IsZero() { + h.LastBlockID = MakeBlockID() + } + if h.ChainID == "" { + h.ChainID = DefaultTestChainID + } + if len(h.LastCommitHash) == 0 { + h.LastCommitHash = RandomHash() + } + if len(h.DataHash) == 0 { + h.DataHash = RandomHash() + } + if len(h.ValidatorsHash) == 0 { + h.ValidatorsHash = RandomHash() + } + if len(h.NextValidatorsHash) == 0 { + h.NextValidatorsHash = RandomHash() + } + if len(h.ConsensusHash) == 0 { + h.ConsensusHash = RandomHash() + } + if len(h.AppHash) == 0 { + h.AppHash = RandomHash() + } + if len(h.LastResultsHash) == 0 { + h.LastResultsHash = RandomHash() + } + if len(h.EvidenceHash) == 0 { + h.EvidenceHash = RandomHash() + } + if len(h.ProposerAddress) == 0 { + h.ProposerAddress = RandomAddress() + } + + return h, h.ValidateBasic() +} + +func MakeRandomHeader() *types.Header { + h, err := MakeHeader(&types.Header{}) + if err != nil { + panic(err) + } + return h +} diff --git a/internal/test/factory/commit.go b/internal/test/factory/commit.go new file mode 100644 index 000000000..d3a392a20 --- /dev/null +++ b/internal/test/factory/commit.go @@ -0,0 +1,48 @@ +package factory + +import ( + "context" + "fmt" + "time" + + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/types" +) + +func MakeCommit(blockID types.BlockID, height int64, round int32, + voteSet *types.VoteSet, validators []types.PrivValidator, now time.Time) (*types.Commit, error) { + + // all sign + for i := 0; i < len(validators); i++ { + pubKey, err := validators[i].GetPubKey(context.Background()) + if err != nil { + return nil, fmt.Errorf("can't get pubkey: %w", err) + } + vote := &types.Vote{ + ValidatorAddress: pubKey.Address(), + ValidatorIndex: int32(i), + Height: height, + Round: round, + Type: tmproto.PrecommitType, + BlockID: blockID, + Timestamp: now, + } + + _, err = signAddVote(validators[i], vote, voteSet) + if err != nil { + return nil, err + } + } + + return voteSet.MakeCommit(), nil +} + +func signAddVote(privVal types.PrivValidator, vote *types.Vote, voteSet *types.VoteSet) (signed bool, err error) { + v := vote.ToProto() + err = privVal.SignVote(context.Background(), voteSet.ChainID(), v) + if err != nil { + return false, err + } + vote.Signature = v.Signature + return voteSet.AddVote(vote) +} diff --git a/internal/test/factory/factory_test.go b/internal/test/factory/factory_test.go new file mode 100644 index 000000000..25f234508 --- /dev/null +++ b/internal/test/factory/factory_test.go @@ -0,0 +1,14 @@ +package factory + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/tendermint/tendermint/types" +) + +func TestMakeHeader(t *testing.T) { + _, err := MakeHeader(&types.Header{}) + assert.NoError(t, err) +} diff --git a/internal/test/factory/genesis.go b/internal/test/factory/genesis.go new file mode 100644 index 000000000..0552b1e8a --- /dev/null +++ b/internal/test/factory/genesis.go @@ -0,0 +1,35 @@ +package factory + +import ( + "sort" + + cfg "github.com/tendermint/tendermint/config" + "github.com/tendermint/tendermint/types" + tmtime "github.com/tendermint/tendermint/types/time" +) + +func RandGenesisDoc( + config *cfg.Config, + numValidators int, + randPower bool, + minPower int64) (*types.GenesisDoc, []types.PrivValidator) { + + validators := make([]types.GenesisValidator, numValidators) + privValidators := make([]types.PrivValidator, numValidators) + for i := 0; i < numValidators; i++ { + val, privVal := RandValidator(randPower, minPower) + validators[i] = types.GenesisValidator{ + PubKey: val.PubKey, + Power: val.VotingPower, + } + privValidators[i] = privVal + } + sort.Sort(types.PrivValidatorsByAddress(privValidators)) + + return &types.GenesisDoc{ + GenesisTime: tmtime.Now(), + InitialHeight: 1, + ChainID: config.ChainID(), + Validators: validators, + }, privValidators +} diff --git a/internal/test/factory/validator.go b/internal/test/factory/validator.go new file mode 100644 index 000000000..428d5d86e --- /dev/null +++ b/internal/test/factory/validator.go @@ -0,0 +1,42 @@ +package factory + +import ( + "context" + "fmt" + "math/rand" + "sort" + + "github.com/tendermint/tendermint/types" +) + +func RandValidator(randPower bool, minPower int64) (*types.Validator, types.PrivValidator) { + privVal := types.NewMockPV() + votePower := minPower + if randPower { + // nolint:gosec // G404: Use of weak random number generator + votePower += int64(rand.Uint32()) + } + pubKey, err := privVal.GetPubKey(context.Background()) + if err != nil { + panic(fmt.Errorf("could not retrieve pubkey %w", err)) + } + val := types.NewValidator(pubKey, votePower) + return val, privVal +} + +func RandValidatorSet(numValidators int, votingPower int64) (*types.ValidatorSet, []types.PrivValidator) { + var ( + valz = make([]*types.Validator, numValidators) + privValidators = make([]types.PrivValidator, numValidators) + ) + + for i := 0; i < numValidators; i++ { + val, privValidator := RandValidator(false, votingPower) + valz[i] = val + privValidators[i] = privValidator + } + + sort.Sort(types.PrivValidatorsByAddress(privValidators)) + + return types.NewValidatorSet(valz), privValidators +} diff --git a/internal/test/factory/vote.go b/internal/test/factory/vote.go new file mode 100644 index 000000000..8d07b008c --- /dev/null +++ b/internal/test/factory/vote.go @@ -0,0 +1,42 @@ +package factory + +import ( + "context" + "time" + + tmproto "github.com/tendermint/tendermint/proto/tendermint/types" + "github.com/tendermint/tendermint/types" +) + +func MakeVote( + val types.PrivValidator, + chainID string, + valIndex int32, + height int64, + round int32, + step int, + blockID types.BlockID, + time time.Time, +) (*types.Vote, error) { + pubKey, err := val.GetPubKey(context.Background()) + if err != nil { + return nil, err + } + v := &types.Vote{ + ValidatorAddress: pubKey.Address(), + ValidatorIndex: valIndex, + Height: height, + Round: round, + Type: tmproto.SignedMsgType(step), + BlockID: blockID, + Timestamp: time, + } + + vpb := v.ToProto() + err = val.SignVote(context.Background(), chainID, vpb) + if err != nil { + panic(err) + } + v.Signature = vpb.Signature + return v, nil +} diff --git a/light/client_test.go b/light/client_test.go index d9bc9410f..a4bfd86b6 100644 --- a/light/client_test.go +++ b/light/client_test.go @@ -11,6 +11,7 @@ import ( dbm "github.com/tendermint/tm-db" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/light" "github.com/tendermint/tendermint/light/provider" @@ -120,7 +121,7 @@ func TestMock(t *testing.T) { func TestClient_SequentialVerification(t *testing.T) { newKeys := genPrivKeys(4) newVals := newKeys.ToValidators(10, 1) - differentVals, _ := types.RandValidatorSet(10, 100) + differentVals, _ := factory.RandValidatorSet(10, 100) testCases := []struct { name string @@ -971,7 +972,7 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) { } func TestClient_TrustedValidatorSet(t *testing.T) { - differentVals, _ := types.RandValidatorSet(10, 100) + differentVals, _ := factory.RandValidatorSet(10, 100) badValSetNode := mockp.New( chainID, map[int64]*types.SignedHeader{ diff --git a/light/store/db/db_test.go b/light/store/db/db_test.go index 6d9b2e27a..b373d5126 100644 --- a/light/store/db/db_test.go +++ b/light/store/db/db_test.go @@ -12,6 +12,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" "github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/version" @@ -183,7 +184,7 @@ func Test_Concurrency(t *testing.T) { } func randLightBlock(height int64) *types.LightBlock { - vals, _ := types.RandValidatorSet(2, 1) + vals, _ := factory.RandValidatorSet(2, 1) return &types.LightBlock{ SignedHeader: &types.SignedHeader{ Header: &types.Header{ diff --git a/state/helpers_test.go b/state/helpers_test.go index 18dd0011a..8163345b3 100644 --- a/state/helpers_test.go +++ b/state/helpers_test.go @@ -11,6 +11,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" cryptoenc "github.com/tendermint/tendermint/crypto/encoding" + "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmstate "github.com/tendermint/tendermint/proto/tendermint/state" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -77,7 +78,7 @@ func makeValidCommit( sigs := make([]types.CommitSig, 0) for i := 0; i < vals.Size(); i++ { _, val := vals.GetByIndex(int32(i)) - vote, err := types.MakeVote(height, blockID, vals, privVals[val.Address.String()], chainID, time.Now()) + vote, err := factory.MakeVote(privVals[val.Address.String()], chainID, int32(i), height, 0, 2, blockID, time.Now()) if err != nil { return nil, err } @@ -261,7 +262,7 @@ func makeRandomStateFromValidatorSet( func makeRandomStateFromConsensusParams(consensusParams *types.ConsensusParams, height, lastHeightConsensusParamsChanged int64) sm.State { - val, _ := types.RandValidator(true, 10) + val, _ := factory.RandValidator(true, 10) valSet := types.NewValidatorSet([]*types.Validator{val}) return sm.State{ LastBlockHeight: height - 1, diff --git a/state/store_test.go b/state/store_test.go index 927f3ff45..467ed34c7 100644 --- a/state/store_test.go +++ b/state/store_test.go @@ -14,6 +14,7 @@ import ( cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/internal/test/factory" tmrand "github.com/tendermint/tendermint/libs/rand" tmstate "github.com/tendermint/tendermint/proto/tendermint/state" sm "github.com/tendermint/tendermint/state" @@ -28,9 +29,9 @@ const ( func TestStoreBootstrap(t *testing.T) { stateDB := dbm.NewMemDB() stateStore := sm.NewStore(stateDB) - val, _ := types.RandValidator(true, 10) - val2, _ := types.RandValidator(true, 10) - val3, _ := types.RandValidator(true, 10) + val, _ := factory.RandValidator(true, 10) + val2, _ := factory.RandValidator(true, 10) + val3, _ := factory.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val, val2, val3}) bootstrapState := makeRandomStateFromValidatorSet(vals, 100, 100) err := stateStore.Bootstrap(bootstrapState) @@ -54,9 +55,9 @@ func TestStoreBootstrap(t *testing.T) { func TestStoreLoadValidators(t *testing.T) { stateDB := dbm.NewMemDB() stateStore := sm.NewStore(stateDB) - val, _ := types.RandValidator(true, 10) - val2, _ := types.RandValidator(true, 10) - val3, _ := types.RandValidator(true, 10) + val, _ := factory.RandValidator(true, 10) + val2, _ := factory.RandValidator(true, 10) + val3, _ := factory.RandValidator(true, 10) vals := types.NewValidatorSet([]*types.Validator{val, val2, val3}) // 1) LoadValidators loads validators using a height where they were last changed diff --git a/state/validation_test.go b/state/validation_test.go index 9019b75e3..065cef766 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -12,6 +12,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/internal/test/factory" "github.com/tendermint/tendermint/libs/log" memmock "github.com/tendermint/tendermint/mempool/mock" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -139,12 +140,14 @@ func TestValidateBlockCommit(t *testing.T) { #2589: ensure state.LastValidators.VerifyCommit fails here */ // should be height-1 instead of height - wrongHeightVote, err := types.MakeVote( - height, - state.LastBlockID, - state.Validators, + wrongHeightVote, err := factory.MakeVote( privVals[proposerAddr.String()], chainID, + 1, + height, + 0, + 2, + state.LastBlockID, time.Now(), ) require.NoError(t, err, "height %d", height) @@ -191,11 +194,14 @@ func TestValidateBlockCommit(t *testing.T) { /* wrongSigsCommit is fine except for the extra bad precommit */ - goodVote, err := types.MakeVote(height, - blockID, - state.Validators, + goodVote, err := factory.MakeVote( privVals[proposerAddr.String()], chainID, + 1, + height, + 0, + 2, + blockID, time.Now(), ) require.NoError(t, err, "height %d", height) diff --git a/test/e2e/runner/evidence.go b/test/e2e/runner/evidence.go index 85a177db6..a9373e355 100644 --- a/test/e2e/runner/evidence.go +++ b/test/e2e/runner/evidence.go @@ -11,6 +11,7 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/tmhash" + "github.com/tendermint/tendermint/internal/test/factory" tmjson "github.com/tendermint/tendermint/libs/json" "github.com/tendermint/tendermint/privval" tmproto "github.com/tendermint/tendermint/proto/tendermint/types" @@ -142,7 +143,7 @@ func generateLightClientAttackEvidence( // create a commit for the forged header blockID := makeBlockID(header.Hash(), 1000, []byte("partshash")) voteSet := types.NewVoteSet(chainID, forgedHeight, 0, tmproto.SignedMsgType(2), conflictingVals) - commit, err := types.MakeCommit(blockID, forgedHeight, 0, voteSet, pv, forgedTime) + commit, err := factory.MakeCommit(blockID, forgedHeight, 0, voteSet, pv, forgedTime) if err != nil { return nil, err } @@ -176,11 +177,13 @@ func generateDuplicateVoteEvidence( ) (*types.DuplicateVoteEvidence, error) { // nolint:gosec // G404: Use of weak random number generator privVal := privVals[rand.Intn(len(privVals))] - voteA, err := types.MakeVote(height, makeRandomBlockID(), vals, privVal, chainID, time) + + valIdx, _ := vals.GetByAddress(privVal.PrivKey.PubKey().Address()) + voteA, err := factory.MakeVote(privVal, chainID, valIdx, height, 0, 2, makeRandomBlockID(), time) if err != nil { return nil, err } - voteB, err := types.MakeVote(height, makeRandomBlockID(), vals, privVal, chainID, time) + voteB, err := factory.MakeVote(privVal, chainID, valIdx, height, 0, 2, makeRandomBlockID(), time) if err != nil { return nil, err } @@ -242,7 +245,7 @@ func makeBlockID(hash []byte, partSetSize uint32, partSetHash []byte) types.Bloc func mutateValidatorSet(privVals []types.MockPV, vals *types.ValidatorSet, ) ([]types.PrivValidator, *types.ValidatorSet, error) { - newVal, newPrivVal := types.RandValidator(false, 10) + newVal, newPrivVal := factory.RandValidator(false, 10) var newVals *types.ValidatorSet if vals.Size() > 2 { diff --git a/types/block.go b/types/block.go index 7716fda16..b48d13653 100644 --- a/types/block.go +++ b/types/block.go @@ -1196,10 +1196,10 @@ func (blockID BlockID) Key() string { func (blockID BlockID) ValidateBasic() error { // Hash can be empty in case of POLBlockID in Proposal. if err := ValidateHash(blockID.Hash); err != nil { - return fmt.Errorf("wrong Hash") + return fmt.Errorf("wrong Hash: %w", err) } if err := blockID.PartSetHeader.ValidateBasic(); err != nil { - return fmt.Errorf("wrong PartSetHeader: %v", err) + return fmt.Errorf("wrong PartSetHeader: %w", err) } return nil } diff --git a/types/block_test.go b/types/block_test.go index 617fefb0f..0022a2ee2 100644 --- a/types/block_test.go +++ b/types/block_test.go @@ -40,7 +40,7 @@ func TestBlockAddEvidence(t *testing.T) { h := int64(3) voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) require.NoError(t, err) ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain") @@ -60,7 +60,7 @@ func TestBlockValidateBasic(t *testing.T) { h := int64(3) voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) require.NoError(t, err) ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain") @@ -137,7 +137,7 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) { h := int64(3) voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) require.NoError(t, err) ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain") @@ -154,7 +154,7 @@ func TestBlockHashesTo(t *testing.T) { lastID := makeBlockIDRandom() h := int64(3) voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) require.NoError(t, err) ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain") @@ -232,7 +232,7 @@ func TestCommit(t *testing.T) { lastID := makeBlockIDRandom() h := int64(3) voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) require.NoError(t, err) assert.Equal(t, h-1, commit.Height) @@ -444,7 +444,7 @@ func randCommit(now time.Time) *Commit { lastID := makeBlockIDRandom() h := int64(3) voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, now) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, now) if err != nil { panic(err) } @@ -525,7 +525,7 @@ func TestCommitToVoteSet(t *testing.T) { h := int64(3) voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1) - commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) + commit, err := makeCommit(lastID, h-1, 1, voteSet, vals, time.Now()) assert.NoError(t, err) chainID := voteSet.ChainID() diff --git a/types/evidence_test.go b/types/evidence_test.go index 29a877664..3187b324a 100644 --- a/types/evidence_test.go +++ b/types/evidence_test.go @@ -98,7 +98,7 @@ func TestLightClientAttackEvidenceBasic(t *testing.T) { header := makeHeaderRandom() header.Height = height blockID := makeBlockID(tmhash.Sum([]byte("blockhash")), math.MaxInt32, tmhash.Sum([]byte("partshash"))) - commit, err := MakeCommit(blockID, height, 1, voteSet, privVals, defaultVoteTime) + commit, err := makeCommit(blockID, height, 1, voteSet, privVals, defaultVoteTime) require.NoError(t, err) lcae := &LightClientAttackEvidence{ ConflictingBlock: &LightBlock{ @@ -158,7 +158,7 @@ func TestLightClientAttackEvidenceValidation(t *testing.T) { header.Height = height header.ValidatorsHash = valSet.Hash() blockID := makeBlockID(header.Hash(), math.MaxInt32, tmhash.Sum([]byte("partshash"))) - commit, err := MakeCommit(blockID, height, 1, voteSet, privVals, time.Now()) + commit, err := makeCommit(blockID, height, 1, voteSet, privVals, time.Now()) require.NoError(t, err) lcae := &LightClientAttackEvidence{ ConflictingBlock: &LightBlock{ diff --git a/types/light_test.go b/types/light_test.go index f3e0af1a6..abf4374d4 100644 --- a/types/light_test.go +++ b/types/light_test.go @@ -14,12 +14,12 @@ import ( func TestLightBlockValidateBasic(t *testing.T) { header := makeRandHeader() commit := randCommit(time.Now()) - vals, _ := RandValidatorSet(5, 1) + vals, _ := randValidatorPrivValSet(5, 1) header.Height = commit.Height header.LastBlockID = commit.BlockID header.ValidatorsHash = vals.Hash() header.Version.Block = version.BlockProtocol - vals2, _ := RandValidatorSet(3, 1) + vals2, _ := randValidatorPrivValSet(3, 1) vals3 := vals.Copy() vals3.Proposer = &Validator{} commit.BlockID.Hash = header.Hash() @@ -59,7 +59,7 @@ func TestLightBlockValidateBasic(t *testing.T) { func TestLightBlockProtobuf(t *testing.T) { header := makeRandHeader() commit := randCommit(time.Now()) - vals, _ := RandValidatorSet(5, 1) + vals, _ := randValidatorPrivValSet(5, 1) header.Height = commit.Height header.LastBlockID = commit.BlockID header.Version.Block = version.BlockProtocol diff --git a/types/test_util.go b/types/test_util.go index 018f24392..f5ec1a976 100644 --- a/types/test_util.go +++ b/types/test_util.go @@ -8,7 +8,7 @@ import ( tmproto "github.com/tendermint/tendermint/proto/tendermint/types" ) -func MakeCommit(blockID BlockID, height int64, round int32, +func makeCommit(blockID BlockID, height int64, round int32, voteSet *VoteSet, validators []PrivValidator, now time.Time) (*Commit, error) { // all sign @@ -45,37 +45,3 @@ func signAddVote(privVal PrivValidator, vote *Vote, voteSet *VoteSet) (signed bo vote.Signature = v.Signature return voteSet.AddVote(vote) } - -func MakeVote( - height int64, - blockID BlockID, - valSet *ValidatorSet, - privVal PrivValidator, - chainID string, - now time.Time, -) (*Vote, error) { - pubKey, err := privVal.GetPubKey(context.Background()) - if err != nil { - return nil, fmt.Errorf("can't get pubkey: %w", err) - } - addr := pubKey.Address() - idx, _ := valSet.GetByAddress(addr) - vote := &Vote{ - ValidatorAddress: addr, - ValidatorIndex: idx, - Height: height, - Round: 0, - Timestamp: now, - Type: tmproto.PrecommitType, - BlockID: blockID, - } - v := vote.ToProto() - - if err := privVal.SignVote(context.Background(), chainID, v); err != nil { - return nil, err - } - - vote.Signature = v.Signature - - return vote, nil -} diff --git a/types/validator.go b/types/validator.go index 46b16deb5..fb3fa2d76 100644 --- a/types/validator.go +++ b/types/validator.go @@ -2,10 +2,8 @@ package types import ( "bytes" - "context" "errors" "fmt" - mrand "math/rand" "strings" "github.com/tendermint/tendermint/crypto" @@ -173,23 +171,3 @@ func ValidatorFromProto(vp *tmproto.Validator) (*Validator, error) { return v, nil } - -//---------------------------------------- -// RandValidator - -// RandValidator returns a randomized validator, useful for testing. -// UNSTABLE -func RandValidator(randPower bool, minPower int64) (*Validator, PrivValidator) { - privVal := NewMockPV() - votePower := minPower - if randPower { - // nolint:gosec // G404: Use of weak random number generator - votePower += int64(mrand.Uint32()) - } - pubKey, err := privVal.GetPubKey(context.Background()) - if err != nil { - panic(fmt.Errorf("could not retrieve pubkey %w", err)) - } - val := NewValidator(pubKey, votePower) - return val, privVal -} diff --git a/types/validator_set.go b/types/validator_set.go index 3cf1baca5..5bc63868a 100644 --- a/types/validator_set.go +++ b/types/validator_set.go @@ -1097,27 +1097,6 @@ func ValidatorSetFromExistingValidators(valz []*Validator) (*ValidatorSet, error //---------------------------------------- -// RandValidatorSet returns a randomized validator set (size: +numValidators+), -// where each validator has a voting power of +votingPower+. -// -// EXPOSED FOR TESTING. -func RandValidatorSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) { - var ( - valz = make([]*Validator, numValidators) - privValidators = make([]PrivValidator, numValidators) - ) - - for i := 0; i < numValidators; i++ { - val, privValidator := RandValidator(false, votingPower) - valz[i] = val - privValidators[i] = privValidator - } - - sort.Sort(PrivValidatorsByAddress(privValidators)) - - return NewValidatorSet(valz), privValidators -} - // safe addition/subtraction/multiplication func safeAdd(a, b int64) (int64, bool) { diff --git a/types/validator_set_test.go b/types/validator_set_test.go index 5e1afbfb2..f3f4552e7 100644 --- a/types/validator_set_test.go +++ b/types/validator_set_test.go @@ -52,7 +52,7 @@ func TestValidatorSetBasic(t *testing.T) { 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55}, vset.Hash()) // add - val = randValidator(vset.TotalVotingPower()) + val = randModuloValidator(vset.TotalVotingPower()) assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val})) assert.True(t, vset.HasAddress(val.Address)) @@ -67,7 +67,7 @@ func TestValidatorSetBasic(t *testing.T) { assert.Equal(t, val.Address, vset.GetProposer().Address) // update - val = randValidator(vset.TotalVotingPower()) + val = randModuloValidator(vset.TotalVotingPower()) assert.NoError(t, vset.UpdateWithChangeSet([]*Validator{val})) _, val = vset.GetByAddress(val.Address) val.VotingPower += 100 @@ -81,7 +81,7 @@ func TestValidatorSetBasic(t *testing.T) { } func TestValidatorSetValidateBasic(t *testing.T) { - val, _ := RandValidator(false, 1) + val, _ := randValidator(false, 1) badVal := &Validator{} testCases := []struct { @@ -139,7 +139,7 @@ func TestValidatorSetValidateBasic(t *testing.T) { } func TestCopy(t *testing.T) { - vset := randValidatorSet(10) + vset := randModuloValidatorSet(10) vsetHash := vset.Hash() if len(vsetHash) == 0 { t.Fatalf("ValidatorSet had unexpected zero hash") @@ -374,7 +374,7 @@ func randPubKey() crypto.PubKey { return ed25519.PubKey(tmrand.Bytes(32)) } -func randValidator(totalVotingPower int64) *Validator { +func randModuloValidator(totalVotingPower int64) *Validator { // this modulo limits the ProposerPriority/VotingPower to stay in the // bounds of MaxTotalVotingPower minus the already existing voting power: val := NewValidator(randPubKey(), int64(rand.Uint64()%uint64(MaxTotalVotingPower-totalVotingPower))) @@ -382,11 +382,25 @@ func randValidator(totalVotingPower int64) *Validator { return val } -func randValidatorSet(numValidators int) *ValidatorSet { +func randValidator(randPower bool, minPower int64) (*Validator, PrivValidator) { + privVal := NewMockPV() + votePower := minPower + if randPower { + votePower += int64(rand.Uint32()) + } + pubKey, err := privVal.GetPubKey(context.Background()) + if err != nil { + panic(fmt.Errorf("could not retrieve pubkey %w", err)) + } + val := NewValidator(pubKey, votePower) + return val, privVal +} + +func randModuloValidatorSet(numValidators int) *ValidatorSet { validators := make([]*Validator, numValidators) totalVotingPower := int64(0) for i := 0; i < numValidators; i++ { - validators[i] = randValidator(totalVotingPower) + validators[i] = randModuloValidator(totalVotingPower) totalVotingPower += validators[i].VotingPower } return NewValidatorSet(validators) @@ -751,7 +765,7 @@ func TestValidatorSet_VerifyCommit_CheckAllSignatures(t *testing.T) { ) voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10) - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(t, err) // malleate 4th signature @@ -776,7 +790,7 @@ func TestValidatorSet_VerifyCommitLight_ReturnsAsSoonAsMajorityOfVotingPowerSign ) voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10) - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(t, err) // malleate 4th signature (3 signatures are enough for 2/3+) @@ -799,7 +813,7 @@ func TestValidatorSet_VerifyCommitLightTrusting_ReturnsAsSoonAsTrustLevelOfVotin ) voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, 4, 10) - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(t, err) // malleate 3rd signature (2 signatures are enough for 1/3+ trust level) @@ -1521,8 +1535,8 @@ func TestValidatorSet_VerifyCommitLightTrusting(t *testing.T) { var ( blockID = makeBlockIDRandom() voteSet, originalValset, vals = randVoteSet(1, 1, tmproto.PrecommitType, 6, 1) - commit, err = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now()) - newValSet, _ = RandValidatorSet(2, 1) + commit, err = makeCommit(blockID, 1, 1, voteSet, vals, time.Now()) + newValSet, _ = randValidatorPrivValSet(2, 1) ) require.NoError(t, err) @@ -1562,7 +1576,7 @@ func TestValidatorSet_VerifyCommitLightTrustingErrorsOnOverflow(t *testing.T) { var ( blockID = makeBlockIDRandom() voteSet, valSet, vals = randVoteSet(1, 1, tmproto.PrecommitType, 1, MaxTotalVotingPower) - commit, err = MakeCommit(blockID, 1, 1, voteSet, vals, time.Now()) + commit, err = makeCommit(blockID, 1, 1, voteSet, vals, time.Now()) ) require.NoError(t, err) @@ -1600,14 +1614,14 @@ func TestSafeMul(t *testing.T) { } func TestValidatorSetProtoBuf(t *testing.T) { - valset, _ := RandValidatorSet(10, 100) - valset2, _ := RandValidatorSet(10, 100) + valset, _ := randValidatorPrivValSet(10, 100) + valset2, _ := randValidatorPrivValSet(10, 100) valset2.Validators[0] = &Validator{} - valset3, _ := RandValidatorSet(10, 100) + valset3, _ := randValidatorPrivValSet(10, 100) valset3.Proposer = nil - valset4, _ := RandValidatorSet(10, 100) + valset4, _ := randValidatorPrivValSet(10, 100) valset4.Proposer = &Validator{} testCases := []struct { @@ -1725,7 +1739,7 @@ func BenchmarkValidatorSet_VerifyCommit_Ed25519(b *testing.B) { // generate n validators voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5)) // create a commit with n validators - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(b, err) for i := 0; i < b.N/n; i++ { @@ -1749,7 +1763,7 @@ func BenchmarkValidatorSet_VerifyCommitLight_Ed25519(b *testing.B) { // generate n validators voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5)) // create a commit with n validators - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(b, err) for i := 0; i < b.N/n; i++ { @@ -1773,7 +1787,7 @@ func BenchmarkValidatorSet_VerifyCommitLightTrusting_Ed25519(b *testing.B) { // generate n validators voteSet, valSet, vals := randVoteSet(h, 0, tmproto.PrecommitType, n, int64(n*5)) // create a commit with n validators - commit, err := MakeCommit(blockID, h, 0, voteSet, vals, time.Now()) + commit, err := makeCommit(blockID, h, 0, voteSet, vals, time.Now()) require.NoError(b, err) for i := 0; i < b.N/n; i++ { diff --git a/types/validator_test.go b/types/validator_test.go index 8f9ff9e04..04d02d5aa 100644 --- a/types/validator_test.go +++ b/types/validator_test.go @@ -9,7 +9,7 @@ import ( ) func TestValidatorProtoBuf(t *testing.T) { - val, _ := RandValidator(true, 100) + val, _ := randValidator(true, 100) testCases := []struct { msg string v1 *Validator diff --git a/types/vote_set_test.go b/types/vote_set_test.go index d2dc31f26..cf1eb916f 100644 --- a/types/vote_set_test.go +++ b/types/vote_set_test.go @@ -3,6 +3,7 @@ package types import ( "bytes" "context" + "sort" "testing" "github.com/stretchr/testify/assert" @@ -483,10 +484,27 @@ func randVoteSet( numValidators int, votingPower int64, ) (*VoteSet, *ValidatorSet, []PrivValidator) { - valSet, privValidators := RandValidatorSet(numValidators, votingPower) + valSet, privValidators := randValidatorPrivValSet(numValidators, votingPower) return NewVoteSet("test_chain_id", height, round, signedMsgType, valSet), valSet, privValidators } +func randValidatorPrivValSet(numValidators int, votingPower int64) (*ValidatorSet, []PrivValidator) { + var ( + valz = make([]*Validator, numValidators) + privValidators = make([]PrivValidator, numValidators) + ) + + for i := 0; i < numValidators; i++ { + val, privValidator := randValidator(false, votingPower) + valz[i] = val + privValidators[i] = privValidator + } + + sort.Sort(PrivValidatorsByAddress(privValidators)) + + return NewValidatorSet(valz), privValidators +} + // Convenience: Return new vote with different validator address/index func withValidator(vote *Vote, addr []byte, idx int32) *Vote { vote = vote.Copy()