From dbfd6fc613dec223ea99740a6f79ef1dd681e229 Mon Sep 17 00:00:00 2001 From: Sam Kleinman Date: Tue, 6 Apr 2021 11:01:48 -0400 Subject: [PATCH] consensus: reduce shared state in tests (#6313) --- consensus/byzantine_test.go | 4 +- consensus/common_test.go | 64 +++++---- consensus/invalid_test.go | 4 +- consensus/mempool_test.go | 20 +-- consensus/reactor_test.go | 21 +-- consensus/replay_test.go | 127 +++++++++++------- consensus/state_test.go | 250 ++++++++++++++++++------------------ 7 files changed, 279 insertions(+), 211 deletions(-) diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 46b752d32..4e10b30b0 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -28,7 +28,7 @@ import ( // Byzantine node sends two different prevotes (nil and blockID) to the same // validator. func TestByzantinePrevoteEquivocation(t *testing.T) { - configSetup(t) + config := configSetup(t) nValidators := 4 prevoteHeight := int64(2) @@ -36,7 +36,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { tickerFunc := newMockTickerFunc(true) appFunc := newCounter - genDoc, privVals := randGenesisDoc(nValidators, false, 30) + genDoc, privVals := 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 48a452de1..c763cafc6 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -42,24 +42,21 @@ import ( const ( testSubscriber = "test-client" + + // genesis, chain_id, priv_val + ensureTimeout = time.Millisecond * 200 ) // A cleanupFunc cleans up any config / test files created for a particular // test. type cleanupFunc func() -// genesis, chain_id, priv_val -var ( - config *cfg.Config // NOTE: must be reset for each _test.go file - consensusReplayConfig *cfg.Config - ensureTimeout = time.Millisecond * 200 -) - -func configSetup(t *testing.T) { +func configSetup(t *testing.T) *cfg.Config { t.Helper() - config = ResetConfig("consensus_reactor_test") - consensusReplayConfig = ResetConfig("consensus_replay_test") + config := ResetConfig("consensus_reactor_test") + + consensusReplayConfig := ResetConfig("consensus_replay_test") configStateTest := ResetConfig("consensus_state_test") configMempoolTest := ResetConfig("consensus_mempool_test") configByzantineTest := ResetConfig("consensus_byzantine_test") @@ -71,6 +68,7 @@ func configSetup(t *testing.T) { os.RemoveAll(configMempoolTest.RootDir) os.RemoveAll(configByzantineTest.RootDir) }) + return config } func ensureDir(dir string, mode os.FileMode) { @@ -94,7 +92,7 @@ type validatorStub struct { VotingPower int64 } -var testMinPower int64 = 10 +const testMinPower int64 = 10 func newValidatorStub(privValidator types.PrivValidator, valIndex int32) *validatorStub { return &validatorStub{ @@ -105,6 +103,7 @@ func newValidatorStub(privValidator types.PrivValidator, valIndex int32) *valida } func (vs *validatorStub) signVote( + config *cfg.Config, voteType tmproto.SignedMsgType, hash []byte, header types.PartSetHeader) (*types.Vote, error) { @@ -131,8 +130,14 @@ func (vs *validatorStub) signVote( } // Sign vote for type/hash/header -func signVote(vs *validatorStub, voteType tmproto.SignedMsgType, hash []byte, header types.PartSetHeader) *types.Vote { - v, err := vs.signVote(voteType, hash, header) +func signVote( + vs *validatorStub, + config *cfg.Config, + voteType tmproto.SignedMsgType, + hash []byte, + header types.PartSetHeader) *types.Vote { + + v, err := vs.signVote(config, voteType, hash, header) if err != nil { panic(fmt.Errorf("failed to sign vote: %v", err)) } @@ -140,13 +145,14 @@ func signVote(vs *validatorStub, voteType tmproto.SignedMsgType, hash []byte, he } func signVotes( + config *cfg.Config, voteType tmproto.SignedMsgType, hash []byte, header types.PartSetHeader, vss ...*validatorStub) []*types.Vote { votes := make([]*types.Vote, len(vss)) for i, vs := range vss { - votes[i] = signVote(vs, voteType, hash, header) + votes[i] = signVote(vs, config, voteType, hash, header) } return votes } @@ -237,13 +243,14 @@ func addVotes(to *State, votes ...*types.Vote) { } func signAddVotes( + config *cfg.Config, to *State, voteType tmproto.SignedMsgType, hash []byte, header types.PartSetHeader, vss ...*validatorStub, ) { - votes := signVotes(voteType, hash, header, vss...) + votes := signVotes(config, voteType, hash, header, vss...) addVotes(to, votes...) } @@ -440,9 +447,9 @@ func loadPrivValidator(config *cfg.Config) *privval.FilePV { return privValidator } -func randState(nValidators int) (*State, []*validatorStub) { +func randState(config *cfg.Config, nValidators int) (*State, []*validatorStub) { // Get State - state, privVals := randGenesisState(nValidators, false, 10) + state, privVals := randGenesisState(config, nValidators, false, 10) vss := make([]*validatorStub, nValidators) @@ -694,6 +701,7 @@ func consensusLogger() log.Logger { } func randConsensusState( + config *cfg.Config, nValidators int, testName string, tickerFunc func() TimeoutTicker, @@ -701,7 +709,7 @@ func randConsensusState( configOpts ...func(*cfg.Config), ) ([]*State, cleanupFunc) { - genDoc, privVals := randGenesisDoc(nValidators, false, 30) + genDoc, privVals := randGenesisDoc(config, nValidators, false, 30) css := make([]*State, nValidators) logger := consensusLogger() @@ -748,15 +756,17 @@ func randConsensusState( // nPeers = nValidators + nNotValidator func randConsensusNetWithPeers( + config *cfg.Config, nValidators, nPeers int, testName string, tickerFunc func() TimeoutTicker, appFunc func(string) abci.Application, ) ([]*State, *types.GenesisDoc, *cfg.Config, cleanupFunc) { - genDoc, privVals := randGenesisDoc(nValidators, false, testMinPower) + genDoc, privVals := randGenesisDoc(config, nValidators, false, testMinPower) css := make([]*State, nPeers) logger := consensusLogger() + var peer0Config *cfg.Config configRootDirs := make([]string, 0, nPeers) for i := 0; i < nPeers; i++ { @@ -808,7 +818,12 @@ func randConsensusNetWithPeers( } } -func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.GenesisDoc, []types.PrivValidator) { +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++ { @@ -829,8 +844,13 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G }, privValidators } -func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) { - genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) +func randGenesisState( + config *cfg.Config, + numValidators int, + randPower bool, + minPower int64) (sm.State, []types.PrivValidator) { + + genDoc, privValidators := randGenesisDoc(config, numValidators, randPower, minPower) s0, _ := sm.MakeGenesisState(genDoc) return s0, privValidators } diff --git a/consensus/invalid_test.go b/consensus/invalid_test.go index 31a4db4f5..816eafd65 100644 --- a/consensus/invalid_test.go +++ b/consensus/invalid_test.go @@ -15,10 +15,10 @@ import ( ) func TestReactorInvalidPrecommit(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 - states, cleanup := randConsensusState(n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) + states, cleanup := randConsensusState(config, n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) t.Cleanup(cleanup) for i := 0; i < 4; i++ { diff --git a/consensus/mempool_test.go b/consensus/mempool_test.go index 85005f9eb..ec301af53 100644 --- a/consensus/mempool_test.go +++ b/consensus/mempool_test.go @@ -25,13 +25,13 @@ func assertMempool(txn txNotifier) mempl.Mempool { } func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { - configSetup(t) + baseConfig := configSetup(t) config := ResetConfig("consensus_mempool_txs_available_test") t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) config.Consensus.CreateEmptyBlocks = false - state, privVals := randGenesisState(1, false, 10) + state, privVals := randGenesisState(baseConfig, 1, false, 10) cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) assertMempool(cs.txNotifier).EnableTxsAvailable() height, round := cs.Height, cs.Round @@ -47,13 +47,13 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { } func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { - configSetup(t) + baseConfig := configSetup(t) config := ResetConfig("consensus_mempool_txs_available_test") t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) config.Consensus.CreateEmptyBlocksInterval = ensureTimeout - state, privVals := randGenesisState(1, false, 10) + state, privVals := randGenesisState(baseConfig, 1, false, 10) cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) assertMempool(cs.txNotifier).EnableTxsAvailable() @@ -67,13 +67,13 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { } func TestMempoolProgressInHigherRound(t *testing.T) { - configSetup(t) + baseConfig := configSetup(t) config := ResetConfig("consensus_mempool_txs_available_test") t.Cleanup(func() { _ = os.RemoveAll(config.RootDir) }) config.Consensus.CreateEmptyBlocks = false - state, privVals := randGenesisState(1, false, 10) + state, privVals := randGenesisState(baseConfig, 1, false, 10) cs := newStateWithConfig(config, state, privVals[0], NewCounterApplication()) assertMempool(cs.txNotifier).EnableTxsAvailable() height, round := cs.Height, cs.Round @@ -119,9 +119,9 @@ func deliverTxsRange(cs *State, start, end int) { } func TestMempoolTxConcurrentWithCommit(t *testing.T) { - configSetup(t) + config := configSetup(t) - state, privVals := randGenesisState(1, false, 10) + state, privVals := randGenesisState(config, 1, false, 10) blockDB := dbm.NewMemDB() stateStore := sm.NewStore(blockDB) cs := newStateWithConfigAndBlockStore(config, state, privVals[0], NewCounterApplication(), blockDB) @@ -145,9 +145,9 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) { } func TestMempoolRmBadTx(t *testing.T) { - configSetup(t) + config := configSetup(t) - state, privVals := randGenesisState(1, false, 10) + state, privVals := randGenesisState(config, 1, false, 10) app := NewCounterApplication() blockDB := dbm.NewMemDB() stateStore := sm.NewStore(blockDB) diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 3d14533c5..e09ddc953 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -246,10 +246,10 @@ func waitForBlockWithUpdatedValsAndValidateIt( } func TestReactorBasic(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 - states, cleanup := randConsensusState(n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) + states, cleanup := randConsensusState(config, n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) t.Cleanup(cleanup) rts := setup(t, n, states, 100) // buffer must be large enough to not deadlock @@ -274,14 +274,14 @@ func TestReactorBasic(t *testing.T) { } func TestReactorWithEvidence(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 testName := "consensus_reactor_test" tickerFunc := newMockTickerFunc(true) appFunc := newCounter - genDoc, privVals := randGenesisDoc(n, false, 30) + genDoc, privVals := randGenesisDoc(config, n, false, 30) states := make([]*State, n) logger := consensusLogger() @@ -369,10 +369,11 @@ func TestReactorWithEvidence(t *testing.T) { } func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 states, cleanup := randConsensusState( + config, n, "consensus_reactor_test", newMockTickerFunc(true), @@ -409,10 +410,10 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) { } func TestReactorRecordsVotesAndBlockParts(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 - states, cleanup := randConsensusState(n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) + states, cleanup := randConsensusState(config, n, "consensus_reactor_test", newMockTickerFunc(true), newCounter) t.Cleanup(cleanup) rts := setup(t, n, states, 100) // buffer must be large enough to not deadlock @@ -466,10 +467,11 @@ func TestReactorRecordsVotesAndBlockParts(t *testing.T) { } func TestReactorVotingPowerChange(t *testing.T) { - configSetup(t) + config := configSetup(t) n := 4 states, cleanup := randConsensusState( + config, n, "consensus_voting_power_changes_test", newMockTickerFunc(true), @@ -565,11 +567,12 @@ func TestReactorVotingPowerChange(t *testing.T) { } func TestReactorValidatorSetChanges(t *testing.T) { - configSetup(t) + config := configSetup(t) nPeers := 7 nVals := 4 states, _, _, cleanup := randConsensusNetWithPeers( + config, nVals, nPeers, "consensus_val_set_changes_test", diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 8175033ab..e51fe1217 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -6,6 +6,7 @@ import ( "fmt" "io" "io/ioutil" + "math/rand" "os" "path/filepath" "runtime" @@ -276,25 +277,21 @@ func (w *crashingWAL) Stop() error { return w.next.Stop() } func (w *crashingWAL) Wait() { w.next.Wait() } //------------------------------------------------------------------------------------------ -type testSim struct { +type simulatorTestSuite struct { GenesisState sm.State Config *cfg.Config Chain []*types.Block Commits []*types.Commit CleanupFunc cleanupFunc + + Mempool mempl.Mempool + Evpool sm.EvidencePool } const ( numBlocks = 6 ) -var ( - mempool = emptyMempool{} - evpool = sm.EmptyEvidencePool{} - - sim testSim -) - //--------------------------------------- // Test handshake/replay @@ -305,12 +302,20 @@ var ( var modes = []uint{0, 1, 2, 3} // This is actually not a test, it's for storing validator change tx data for testHandshakeReplay -func TestSimulateValidatorsChange(t *testing.T) { - configSetup(t) +func setupSimulator(t *testing.T) *simulatorTestSuite { + t.Helper() + config := configSetup(t) + + sim := &simulatorTestSuite{ + Mempool: emptyMempool{}, + Evpool: sm.EmptyEvidencePool{}, + } nPeers := 7 nVals := 4 + css, genDoc, config, cleanup := randConsensusNetWithPeers( + config, nVals, nPeers, "replay_test", @@ -337,7 +342,11 @@ func TestSimulateValidatorsChange(t *testing.T) { ensureNewRound(newRoundCh, height, 0) ensureNewProposal(proposalCh, height, round) rs := css[0].GetRoundState() - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:nVals]...) + + signAddVotes(sim.Config, css[0], tmproto.PrecommitType, + rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), + vss[1:nVals]...) + ensureNewRound(newRoundCh, height+1, 0) // HEIGHT 2 @@ -367,7 +376,9 @@ func TestSimulateValidatorsChange(t *testing.T) { } ensureNewProposal(proposalCh, height, round) rs = css[0].GetRoundState() - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:nVals]...) + signAddVotes(sim.Config, css[0], tmproto.PrecommitType, + rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), + vss[1:nVals]...) ensureNewRound(newRoundCh, height+1, 0) // HEIGHT 3 @@ -397,7 +408,9 @@ func TestSimulateValidatorsChange(t *testing.T) { } ensureNewProposal(proposalCh, height, round) rs = css[0].GetRoundState() - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:nVals]...) + signAddVotes(sim.Config, css[0], tmproto.PrecommitType, + rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), + vss[1:nVals]...) ensureNewRound(newRoundCh, height+1, 0) // HEIGHT 4 @@ -463,7 +476,9 @@ func TestSimulateValidatorsChange(t *testing.T) { if i == selfIndex { continue } - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), newVss[i]) + signAddVotes(sim.Config, css[0], + tmproto.PrecommitType, rs.ProposalBlock.Hash(), + rs.ProposalBlockParts.Header(), newVss[i]) } ensureNewRound(newRoundCh, height+1, 0) @@ -482,7 +497,9 @@ func TestSimulateValidatorsChange(t *testing.T) { if i == selfIndex { continue } - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), newVss[i]) + signAddVotes(sim.Config, css[0], + tmproto.PrecommitType, rs.ProposalBlock.Hash(), + rs.ProposalBlockParts.Header(), newVss[i]) } ensureNewRound(newRoundCh, height+1, 0) @@ -517,7 +534,9 @@ func TestSimulateValidatorsChange(t *testing.T) { if i == selfIndex { continue } - signAddVotes(css[0], tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), newVss[i]) + signAddVotes(sim.Config, css[0], + tmproto.PrecommitType, rs.ProposalBlock.Hash(), + rs.ProposalBlockParts.Header(), newVss[i]) } ensureNewRound(newRoundCh, height+1, 0) @@ -527,61 +546,67 @@ func TestSimulateValidatorsChange(t *testing.T) { sim.Chain = append(sim.Chain, css[0].blockStore.LoadBlock(int64(i))) sim.Commits = append(sim.Commits, css[0].blockStore.LoadBlockCommit(int64(i))) } + if sim.CleanupFunc != nil { + t.Cleanup(sim.CleanupFunc) + } + + return sim } // Sync from scratch func TestHandshakeReplayAll(t *testing.T) { - configSetup(t) + sim := setupSimulator(t) for _, m := range modes { - testHandshakeReplay(t, config, 0, m, false) + testHandshakeReplay(t, sim, 0, m, false) } for _, m := range modes { - testHandshakeReplay(t, config, 0, m, true) + testHandshakeReplay(t, sim, 0, m, true) } } // Sync many, not from scratch func TestHandshakeReplaySome(t *testing.T) { - configSetup(t) + sim := setupSimulator(t) for _, m := range modes { - testHandshakeReplay(t, config, 2, m, false) + testHandshakeReplay(t, sim, 2, m, false) } for _, m := range modes { - testHandshakeReplay(t, config, 2, m, true) + testHandshakeReplay(t, sim, 2, m, true) } } // Sync from lagging by one func TestHandshakeReplayOne(t *testing.T) { - configSetup(t) + sim := setupSimulator(t) for _, m := range modes { - testHandshakeReplay(t, config, numBlocks-1, m, false) + testHandshakeReplay(t, sim, numBlocks-1, m, false) } for _, m := range modes { - testHandshakeReplay(t, config, numBlocks-1, m, true) + testHandshakeReplay(t, sim, numBlocks-1, m, true) } } // Sync from caught up func TestHandshakeReplayNone(t *testing.T) { - configSetup(t) + sim := setupSimulator(t) for _, m := range modes { - testHandshakeReplay(t, config, numBlocks, m, false) + testHandshakeReplay(t, sim, numBlocks, m, false) } for _, m := range modes { - testHandshakeReplay(t, config, numBlocks, m, true) + testHandshakeReplay(t, sim, numBlocks, m, true) } } // Test mockProxyApp should not panic when app return ABCIResponses with some empty ResponseDeliverTx func TestMockProxyApp(t *testing.T) { - configSetup(t) + sim := setupSimulator(t) // setup config and simulator + config := sim.Config + assert.NotNil(t, config) - sim.CleanupFunc() // clean the test env created in TestSimulateValidatorsChange logger := log.TestingLogger() var validTxs, invalidTxs = 0, 0 txIndex := 0 @@ -648,12 +673,15 @@ func tempWALWithData(data []byte) string { // Make some blocks. Start a fresh app and apply nBlocks blocks. // Then restart the app and sync it up with the remaining blocks -func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uint, testValidatorsChange bool) { +func testHandshakeReplay(t *testing.T, sim *simulatorTestSuite, nBlocks int, mode uint, testValidatorsChange bool) { var chain []*types.Block var commits []*types.Commit var store *mockBlockStore var stateDB dbm.DB var genesisState sm.State + + config := sim.Config + if testValidatorsChange { testConfig := ResetConfig(fmt.Sprintf("%s_%v_m", t.Name(), mode)) defer func() { _ = os.RemoveAll(testConfig.RootDir) }() @@ -698,12 +726,12 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin state := genesisState.Copy() // run the chain through state.ApplyBlock to build up the tendermint state - state = buildTMStateFromChain(config, stateStore, state, chain, nBlocks, mode) + state = buildTMStateFromChain(config, sim.Mempool, sim.Evpool, stateStore, state, chain, nBlocks, mode) latestAppHash := state.AppHash // make a new client creator kvstoreApp := kvstore.NewPersistentKVStoreApplication( - filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_a", nBlocks, mode))) + filepath.Join(config.DBDir(), fmt.Sprintf("replay_test_%d_%d_a_r%d", nBlocks, mode, rand.Int()))) t.Cleanup(func() { require.NoError(t, kvstoreApp.Close()) }) clientCreator2 := proxy.NewLocalClientCreator(kvstoreApp) @@ -715,7 +743,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin stateStore := sm.NewStore(stateDB1) err := stateStore.Save(genesisState) require.NoError(t, err) - buildAppStateFromChain(proxyApp, stateStore, genesisState, chain, nBlocks, mode) + buildAppStateFromChain(proxyApp, stateStore, sim.Mempool, sim.Evpool, genesisState, chain, nBlocks, mode) } // Prune block store if requested @@ -775,7 +803,12 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } } -func applyBlock(stateStore sm.Store, st sm.State, blk *types.Block, proxyApp proxy.AppConns) sm.State { +func applyBlock(stateStore sm.Store, + mempool mempl.Mempool, + evpool sm.EvidencePool, + st sm.State, + blk *types.Block, + proxyApp proxy.AppConns) sm.State { testPartSize := types.BlockPartSizeBytes blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) @@ -787,8 +820,14 @@ func applyBlock(stateStore sm.Store, st sm.State, blk *types.Block, proxyApp pro return newState } -func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, - state sm.State, chain []*types.Block, nBlocks int, mode uint) { +func buildAppStateFromChain( + proxyApp proxy.AppConns, + stateStore sm.Store, + mempool mempl.Mempool, + evpool sm.EvidencePool, + state sm.State, + chain []*types.Block, + nBlocks int, mode uint) { // start a new app without handshake, play nBlocks blocks if err := proxyApp.Start(); err != nil { panic(err) @@ -809,18 +848,18 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, case 0: for i := 0; i < nBlocks; i++ { block := chain[i] - state = applyBlock(stateStore, state, block, proxyApp) + state = applyBlock(stateStore, mempool, evpool, state, block, proxyApp) } case 1, 2, 3: for i := 0; i < nBlocks-1; i++ { block := chain[i] - state = applyBlock(stateStore, state, block, proxyApp) + state = applyBlock(stateStore, mempool, evpool, state, block, proxyApp) } if mode == 2 || mode == 3 { // update the kvstore height and apphash // as if we ran commit but not - state = applyBlock(stateStore, state, chain[nBlocks-1], proxyApp) + state = applyBlock(stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp) } default: panic(fmt.Sprintf("unknown mode %v", mode)) @@ -830,6 +869,8 @@ func buildAppStateFromChain(proxyApp proxy.AppConns, stateStore sm.Store, func buildTMStateFromChain( config *cfg.Config, + mempool mempl.Mempool, + evpool sm.EvidencePool, stateStore sm.Store, state sm.State, chain []*types.Block, @@ -861,19 +902,19 @@ func buildTMStateFromChain( case 0: // sync right up for _, block := range chain { - state = applyBlock(stateStore, state, block, proxyApp) + state = applyBlock(stateStore, mempool, evpool, state, block, proxyApp) } case 1, 2, 3: // sync up to the penultimate as if we stored the block. // whether we commit or not depends on the appHash for _, block := range chain[:len(chain)-1] { - state = applyBlock(stateStore, state, block, proxyApp) + state = applyBlock(stateStore, mempool, evpool, state, block, proxyApp) } // apply the final block to a state copy so we can // get the right next appHash but keep the state back - applyBlock(stateStore, state, chain[len(chain)-1], proxyApp) + applyBlock(stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp) default: panic(fmt.Sprintf("unknown mode %v", mode)) } diff --git a/consensus/state_test.go b/consensus/state_test.go index de0f6cc09..63c75a4a4 100644 --- a/consensus/state_test.go +++ b/consensus/state_test.go @@ -56,9 +56,9 @@ x * TestHalt1 - if we see +2/3 precommits after timing out into new round, we sh // ProposeSuite func TestStateProposerSelection0(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) height, round := cs1.Height, cs1.Round newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) @@ -82,7 +82,7 @@ func TestStateProposerSelection0(t *testing.T) { ensureNewProposal(proposalCh, height, round) rs := cs1.GetRoundState() - signAddVotes(cs1, tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...) + signAddVotes(config, cs1, tmproto.PrecommitType, rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), vss[1:]...) // Wait for new round so next validator is set. ensureNewRound(newRoundCh, height+1, 0) @@ -98,9 +98,9 @@ func TestStateProposerSelection0(t *testing.T) { // Now let's do it all again, but starting from round 2 instead of 0 func TestStateProposerSelection2(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) // test needs more work for more than 3 validators + cs1, vss := randState(config, 4) // test needs more work for more than 3 validators height := cs1.Height newRoundCh := subscribe(cs1.eventBus, types.EventQueryNewRound) @@ -128,7 +128,7 @@ func TestStateProposerSelection2(t *testing.T) { } rs := cs1.GetRoundState() - signAddVotes(cs1, tmproto.PrecommitType, nil, rs.ProposalBlockParts.Header(), vss[1:]...) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, rs.ProposalBlockParts.Header(), vss[1:]...) ensureNewRound(newRoundCh, height, i+round+1) // wait for the new round event each round incrementRound(vss[1:]...) } @@ -137,9 +137,9 @@ func TestStateProposerSelection2(t *testing.T) { // a non-validator should timeout into the prevote round func TestStateEnterProposeNoPrivValidator(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs, _ := randState(1) + cs, _ := randState(config, 1) cs.SetPrivValidator(nil) height, round := cs.Height, cs.Round @@ -158,9 +158,9 @@ func TestStateEnterProposeNoPrivValidator(t *testing.T) { // a validator should not timeout of the prevote round (TODO: unless the block is really big!) func TestStateEnterProposeYesPrivValidator(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs, _ := randState(1) + cs, _ := randState(config, 1) height, round := cs.Height, cs.Round // Listen for propose timeout event @@ -190,9 +190,9 @@ func TestStateEnterProposeYesPrivValidator(t *testing.T) { } func TestStateBadProposal(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(2) + cs1, vss := randState(config, 2) height, round := cs1.Height, cs1.Round vs2 := vss[1] @@ -240,19 +240,19 @@ func TestStateBadProposal(t *testing.T) { validatePrevote(t, cs1, round, vss[0], nil) // add bad prevote from vs2 and wait for it - signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) ensurePrevote(voteCh, height, round) // wait for precommit ensurePrecommit(voteCh, height, round) validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) - signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) } func TestStateOversizedBlock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(2) + cs1, vss := randState(config, 2) cs1.state.ConsensusParams.Block.MaxBytes = 2000 height, round := cs1.Height, cs1.Round vs2 := vss[1] @@ -302,11 +302,11 @@ func TestStateOversizedBlock(t *testing.T) { // precommit on it ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], nil) - signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) ensurePrevote(voteCh, height, round) ensurePrecommit(voteCh, height, round) validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) - signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) } //---------------------------------------------------------------------------------------------------- @@ -314,9 +314,9 @@ func TestStateOversizedBlock(t *testing.T) { // propose, prevote, and precommit a block func TestStateFullRound1(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs, vss := randState(1) + cs, vss := randState(config, 1) height, round := cs.Height, cs.Round // NOTE: buffer capacity of 0 ensures we can validate prevote and last commit @@ -356,9 +356,9 @@ func TestStateFullRound1(t *testing.T) { // nil is proposed, so prevote and precommit nil func TestStateFullRoundNil(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs, vss := randState(1) + cs, vss := randState(config, 1) height, round := cs.Height, cs.Round voteCh := subscribeUnBuffered(cs.eventBus, types.EventQueryVote) @@ -376,9 +376,9 @@ func TestStateFullRoundNil(t *testing.T) { // run through propose, prevote, precommit commit with two validators // where the first validator has to wait for votes from the second func TestStateFullRound2(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(2) + cs1, vss := randState(config, 2) vs2 := vss[1] height, round := cs1.Height, cs1.Round @@ -395,7 +395,7 @@ func TestStateFullRound2(t *testing.T) { propBlockHash, propPartSetHeader := rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header() // prevote arrives from vs2: - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propPartSetHeader, vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propPartSetHeader, vs2) ensurePrevote(voteCh, height, round) // prevote ensurePrecommit(voteCh, height, round) // precommit @@ -405,7 +405,7 @@ func TestStateFullRound2(t *testing.T) { // we should be stuck in limbo waiting for more precommits // precommit arrives from vs2: - signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propPartSetHeader, vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propPartSetHeader, vs2) ensurePrecommit(voteCh, height, round) // wait to finish commit, propose in next height @@ -418,9 +418,9 @@ func TestStateFullRound2(t *testing.T) { // two validators, 4 rounds. // two vals take turns proposing. val1 locks on first one, precommits nil on everything else func TestStateLockNoPOL(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(2) + cs1, vss := randState(config, 2) vs2 := vss[1] height, round := cs1.Height, cs1.Round @@ -451,7 +451,7 @@ func TestStateLockNoPOL(t *testing.T) { // we should now be stuck in limbo forever, waiting for more prevotes // prevote arrives from vs2: - signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, thePartSetHeader, vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, thePartSetHeader, vs2) ensurePrevote(voteCh, height, round) // prevote ensurePrecommit(voteCh, height, round) // precommit @@ -463,7 +463,7 @@ func TestStateLockNoPOL(t *testing.T) { hash := make([]byte, len(theBlockHash)) copy(hash, theBlockHash) hash[0] = (hash[0] + 1) % 255 - signAddVotes(cs1, tmproto.PrecommitType, hash, thePartSetHeader, vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, hash, thePartSetHeader, vs2) ensurePrecommit(voteCh, height, round) // precommit // (note we're entering precommit for a second time this round) @@ -496,7 +496,7 @@ func TestStateLockNoPOL(t *testing.T) { validatePrevote(t, cs1, round, vss[0], rs.LockedBlock.Hash()) // add a conflicting prevote from the other validator - signAddVotes(cs1, tmproto.PrevoteType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) ensurePrevote(voteCh, height, round) // now we're going to enter prevote again, but with invalid args @@ -509,7 +509,7 @@ func TestStateLockNoPOL(t *testing.T) { validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // add conflicting precommit from vs2 - signAddVotes(cs1, tmproto.PrecommitType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, hash, rs.LockedBlock.MakePartSet(partSize).Header(), vs2) ensurePrecommit(voteCh, height, round) // (note we're entering precommit for a second time this round, but with invalid args @@ -539,7 +539,7 @@ func TestStateLockNoPOL(t *testing.T) { ensurePrevote(voteCh, height, round) // prevote validatePrevote(t, cs1, round, vss[0], rs.LockedBlock.Hash()) - signAddVotes(cs1, tmproto.PrevoteType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, hash, rs.ProposalBlock.MakePartSet(partSize).Header(), vs2) ensurePrevote(voteCh, height, round) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) @@ -548,6 +548,7 @@ func TestStateLockNoPOL(t *testing.T) { validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but be locked on proposal signAddVotes( + config, cs1, tmproto.PrecommitType, hash, @@ -557,7 +558,7 @@ func TestStateLockNoPOL(t *testing.T) { ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) - cs2, _ := randState(2) // needed so generated block is different than locked block + cs2, _ := randState(config, 2) // needed so generated block is different than locked block // before we time out into new round, set next proposal block prop, propBlock := decideProposal(cs2, vs2, vs2.Height, vs2.Round+1) if prop == nil || propBlock == nil { @@ -585,7 +586,7 @@ func TestStateLockNoPOL(t *testing.T) { validatePrevote(t, cs1, 3, vss[0], cs1.LockedBlock.Hash()) // prevote for proposed block - signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2) ensurePrevote(voteCh, height, round) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) @@ -593,6 +594,7 @@ func TestStateLockNoPOL(t *testing.T) { validatePrecommit(t, cs1, round, 0, vss[0], nil, theBlockHash) // precommit nil but locked on proposal signAddVotes( + config, cs1, tmproto.PrecommitType, propBlock.Hash(), @@ -606,9 +608,9 @@ func TestStateLockNoPOL(t *testing.T) { // in round two: v1 prevotes the same block that the node is locked on // the others prevote a new block hence v1 changes lock and precommits the new block with the others func TestStateLockPOLRelock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -642,14 +644,14 @@ func TestStateLockPOLRelock(t *testing.T) { ensurePrevote(voteCh, height, round) // prevote - signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // our precommit // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) // add precommits from the rest - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal cs2 := newState(cs1.state, vs2, counter.NewApplication(true)) @@ -690,14 +692,14 @@ func TestStateLockPOLRelock(t *testing.T) { validatePrevote(t, cs1, round, vss[0], theBlockHash) // now lets add prevotes from everyone else for the new block - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // we should have unlocked and locked on the new block, sending a precommit for this new block validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) // more prevote creating a majority on the new block and this is then committed - signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3) ensureNewBlockHeader(newBlockCh, height, propBlockHash) ensureNewRound(newRoundCh, height+1, 0) @@ -705,9 +707,9 @@ func TestStateLockPOLRelock(t *testing.T) { // 4 vals, one precommits, other 3 polka at next round, so we unlock and precomit the polka func TestStateLockPOLUnlock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -741,15 +743,15 @@ func TestStateLockPOLUnlock(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], theBlockHash) - signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) // add precommits from the rest - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) - signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) // before we time out into new round, set next proposal block prop, propBlock := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) @@ -780,7 +782,7 @@ func TestStateLockPOLUnlock(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], lockedBlockHash) // now lets add prevotes from everyone else for nil (a polka!) - signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // the polka makes us unlock and precommit nil ensureNewUnlock(unlockCh, height, round) @@ -790,7 +792,7 @@ func TestStateLockPOLUnlock(t *testing.T) { // NOTE: since we don't relock on nil, the lock round is -1 validatePrecommit(t, cs1, round, -1, vss[0], nil, nil) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3) ensureNewRound(newRoundCh, height, round+1) } @@ -799,9 +801,9 @@ func TestStateLockPOLUnlock(t *testing.T) { // v1 should unlock and precommit nil. In the third round another block is proposed, all vals // prevote and now v1 can lock onto the third block and precommit that func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -831,14 +833,14 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { ensurePrevote(voteCh, height, round) // prevote - signAddVotes(cs1, tmproto.PrevoteType, firstBlockHash, firstBlockParts, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, firstBlockHash, firstBlockParts, vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // our precommit // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], firstBlockHash, firstBlockHash) // add precommits from the rest - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal cs2 := newState(cs1.state, vs2, counter.NewApplication(true)) @@ -871,7 +873,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { validatePrevote(t, cs1, round, vss[0], firstBlockHash) // now lets add prevotes from everyone else for the new block - signAddVotes(cs1, tmproto.PrevoteType, secondBlockHash, secondBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, secondBlockHash, secondBlockParts.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // we should have unlocked and locked on the new block, sending a precommit for this new block @@ -882,7 +884,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { } // more prevote creating a majority on the new block and this is then committed - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // before we timeout to the new round set the new proposal cs3 := newState(cs1.state, vs3, counter.NewApplication(true)) @@ -915,7 +917,7 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { // we are no longer locked to the first block so we should be able to prevote validatePrevote(t, cs1, round, vss[0], thirdPropBlockHash) - signAddVotes(cs1, tmproto.PrevoteType, thirdPropBlockHash, thirdPropBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, thirdPropBlockHash, thirdPropBlockParts.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // we have a majority, now vs1 can change lock to the third block @@ -927,9 +929,9 @@ func TestStateLockPOLUnlockOnUnknownBlock(t *testing.T) { // then a polka at round 2 that we lock on // then we see the polka from round 1 but shouldn't unlock func TestStateLockPOLSafety1(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -956,12 +958,14 @@ func TestStateLockPOLSafety1(t *testing.T) { validatePrevote(t, cs1, round, vss[0], propBlock.Hash()) // the others sign a polka but we don't see it - prevotes := signVotes(tmproto.PrevoteType, propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) + prevotes := signVotes(config, tmproto.PrevoteType, + propBlock.Hash(), propBlock.MakePartSet(partSize).Header(), + vs2, vs3, vs4) t.Logf("old prop hash %v", fmt.Sprintf("%X", propBlock.Hash())) // we do see them precommit nil - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) // cs1 precommit nil ensurePrecommit(voteCh, height, round) @@ -1001,13 +1005,13 @@ func TestStateLockPOLSafety1(t *testing.T) { validatePrevote(t, cs1, round, vss[0], propBlockHash) // now we see the others prevote for it, so we should lock on it - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // we should have precommitted validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) @@ -1048,9 +1052,9 @@ func TestStateLockPOLSafety1(t *testing.T) { // What we want: // dont see P0, lock on P1 at R1, dont unlock using P0 at R2 func TestStateLockPOLSafety2(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1073,7 +1077,7 @@ func TestStateLockPOLSafety2(t *testing.T) { propBlockID0 := types.BlockID{Hash: propBlockHash0, PartSetHeader: propBlockParts0.Header()} // the others sign a polka but we don't see it - prevotes := signVotes(tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) + prevotes := signVotes(config, tmproto.PrevoteType, propBlockHash0, propBlockParts0.Header(), vs2, vs3, vs4) // the block for round 1 prop1, propBlock1 := decideProposal(cs1, vs2, vs2.Height, vs2.Round+1) @@ -1096,15 +1100,15 @@ func TestStateLockPOLSafety2(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], propBlockHash1) - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash1, propBlockParts1.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash1, propBlockParts1.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], propBlockHash1, propBlockHash1) // add precommits from the rest - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) - signAddVotes(cs1, tmproto.PrecommitType, propBlockHash1, propBlockParts1.Header(), vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash1, propBlockParts1.Header(), vs3) incrementRound(vs2, vs3, vs4) @@ -1147,9 +1151,9 @@ func TestStateLockPOLSafety2(t *testing.T) { // What we want: // P0 proposes B0 at R3. func TestProposeValidBlock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1178,13 +1182,13 @@ func TestProposeValidBlock(t *testing.T) { validatePrevote(t, cs1, round, vss[0], propBlockHash) // the others sign a polka - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlock.MakePartSet(partSize).Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // we should have precommitted validatePrecommit(t, cs1, round, round, vss[0], propBlockHash, propBlockHash) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) @@ -1201,7 +1205,7 @@ func TestProposeValidBlock(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], propBlockHash) - signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) ensureNewUnlock(unlockCh, height, round) @@ -1212,7 +1216,7 @@ func TestProposeValidBlock(t *testing.T) { incrementRound(vs2, vs3, vs4) incrementRound(vs2, vs3, vs4) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) round += 2 // moving to the next round @@ -1239,9 +1243,9 @@ func TestProposeValidBlock(t *testing.T) { // What we want: // P0 miss to lock B but set valid block to B after receiving delayed prevote. func TestSetValidBlockOnDelayedPrevote(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1270,10 +1274,10 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { validatePrevote(t, cs1, round, vss[0], propBlockHash) // vs2 send prevote for propBlock - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2) // vs3 send prevote nil - signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs3) + signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs3) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) @@ -1288,7 +1292,7 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { assert.True(t, rs.ValidRound == -1) // vs2 send (delayed) prevote for propBlock - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs4) ensureNewValidBlock(validBlockCh, height, round) @@ -1303,9 +1307,9 @@ func TestSetValidBlockOnDelayedPrevote(t *testing.T) { // P0 miss to lock B as Proposal Block is missing, but set valid block to B after // receiving delayed Block Proposal. func TestSetValidBlockOnDelayedProposal(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1337,7 +1341,7 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { propBlockParts := propBlock.MakePartSet(partSize) // vs2, vs3 and vs4 send prevote for propBlock - signAddVotes(cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) ensureNewValidBlock(validBlockCh, height, round) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Prevote(round).Nanoseconds()) @@ -1361,9 +1365,9 @@ func TestSetValidBlockOnDelayedProposal(t *testing.T) { // What we want: // P0 waits for timeoutPrecommit before starting next round func TestWaitingTimeoutOnNilPolka(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1374,7 +1378,7 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { startTestRound(cs1, height, round) ensureNewRound(newRoundCh, height, round) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) ensureNewTimeout(timeoutWaitCh, height, round, cs1.config.Precommit(round).Nanoseconds()) ensureNewRound(newRoundCh, height, round+1) @@ -1384,9 +1388,9 @@ func TestWaitingTimeoutOnNilPolka(t *testing.T) { // What we want: // P0 waits for timeoutPropose in the next round before entering prevote func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1404,7 +1408,7 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { ensurePrevote(voteCh, height, round) incrementRound(vss[1:]...) - signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) round++ // moving to the next round ensureNewRound(newRoundCh, height, round) @@ -1422,9 +1426,9 @@ func TestWaitingTimeoutProposeOnNewRound(t *testing.T) { // What we want: // P0 jump to higher round, precommit and start precommit wait func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1442,7 +1446,7 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { ensurePrevote(voteCh, height, round) incrementRound(vss[1:]...) - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2, vs3, vs4) round++ // moving to the next round ensureNewRound(newRoundCh, height, round) @@ -1460,9 +1464,9 @@ func TestRoundSkipOnNilPolkaFromHigherRound(t *testing.T) { // What we want: // P0 wait for timeoutPropose to expire before sending prevote. func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, int32(1) @@ -1478,7 +1482,7 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { ensureNewRound(newRoundCh, height, round) incrementRound(vss[1:]...) - signAddVotes(cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, nil, types.PartSetHeader{}, vs2, vs3, vs4) ensureNewTimeout(timeoutProposeCh, height, round, cs1.config.Propose(round).Nanoseconds()) @@ -1489,9 +1493,9 @@ func TestWaitTimeoutProposeOnNilPolkaForTheCurrentRound(t *testing.T) { // What we want: // P0 emit NewValidBlock event upon receiving 2/3+ Precommit for B but hasn't received block B yet func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, int32(1) @@ -1511,7 +1515,7 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { ensureNewRound(newRoundCh, height, round) // vs2, vs3 and vs4 send precommit for propBlock - signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) ensureNewValidBlock(validBlockCh, height, round) rs := cs1.GetRoundState() @@ -1525,9 +1529,9 @@ func TestEmitNewValidBlockEventOnCommitWithoutBlock(t *testing.T) { // P0 receives 2/3+ Precommit for B for round 0, while being in round 1. It emits NewValidBlock event. // After receiving block, it executes block and moves to the next height. func TestCommitFromPreviousRound(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, int32(1) @@ -1546,7 +1550,7 @@ func TestCommitFromPreviousRound(t *testing.T) { ensureNewRound(newRoundCh, height, round) // vs2, vs3 and vs4 send precommit for propBlock for the previous round - signAddVotes(cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, propBlockHash, propBlockParts.Header(), vs2, vs3, vs4) ensureNewValidBlock(validBlockCh, height, round) @@ -1580,10 +1584,10 @@ func (n *fakeTxNotifier) Notify() { // and third precommit arrives which leads to the commit of that header and the correct // start of the next round func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { - configSetup(t) + config := configSetup(t) config.Consensus.SkipTimeoutCommit = false - cs1, vss := randState(4) + cs1, vss := randState(config, 4) cs1.txNotifier = &fakeTxNotifier{ch: make(chan struct{})} vs2, vs3, vs4 := vss[1], vss[2], vss[3] @@ -1612,15 +1616,15 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], theBlockHash) - signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) // add precommits - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) - signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) // wait till timeout occurs ensurePrecommitTimeout(precommitTimeoutCh) @@ -1628,7 +1632,7 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { ensureNewRound(newRoundCh, height, round+1) // majority is now reached - signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) ensureNewBlockHeader(newBlockHeader, height, theBlockHash) @@ -1643,10 +1647,10 @@ func TestStartNextHeightCorrectlyAfterTimeout(t *testing.T) { } func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { - configSetup(t) + config := configSetup(t) config.Consensus.SkipTimeoutCommit = false - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round @@ -1674,15 +1678,15 @@ func TestResetTimeoutPrecommitUponNewHeight(t *testing.T) { ensurePrevote(voteCh, height, round) validatePrevote(t, cs1, round, vss[0], theBlockHash) - signAddVotes(cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, theBlockHash, theBlockParts, vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) validatePrecommit(t, cs1, round, round, vss[0], theBlockHash, theBlockHash) // add precommits - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) - signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) - signAddVotes(cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) + signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, theBlockHash, theBlockParts, vs4) ensureNewBlockHeader(newBlockHeader, height, theBlockHash) @@ -1787,9 +1791,9 @@ func TestStateSlashingPrecommits(t *testing.T) { // 4 vals. // we receive a final precommit after going into next round, but others might have gone to commit already! func TestStateHalt1(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs1, vss := randState(4) + cs1, vss := randState(config, 4) vs2, vs3, vs4 := vss[1], vss[2], vss[3] height, round := cs1.Height, cs1.Round partSize := types.BlockPartSizeBytes @@ -1814,17 +1818,17 @@ func TestStateHalt1(t *testing.T) { ensurePrevote(voteCh, height, round) - signAddVotes(cs1, tmproto.PrevoteType, propBlock.Hash(), propBlockParts.Header(), vs2, vs3, vs4) + signAddVotes(config, cs1, tmproto.PrevoteType, propBlock.Hash(), propBlockParts.Header(), vs2, vs3, vs4) ensurePrecommit(voteCh, height, round) // the proposed block should now be locked and our precommit added validatePrecommit(t, cs1, round, round, vss[0], propBlock.Hash(), propBlock.Hash()) // add precommits from the rest - signAddVotes(cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) // didnt receive proposal - signAddVotes(cs1, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header(), vs3) + signAddVotes(config, cs1, tmproto.PrecommitType, nil, types.PartSetHeader{}, vs2) // didnt receive proposal + signAddVotes(config, cs1, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header(), vs3) // we receive this later, but vs3 might receive it earlier and with ours will go to commit! - precommit4 := signVote(vs4, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header()) + precommit4 := signVote(vs4, config, tmproto.PrecommitType, propBlock.Hash(), propBlockParts.Header()) incrementRound(vs2, vs3, vs4) @@ -1856,10 +1860,10 @@ func TestStateHalt1(t *testing.T) { } func TestStateOutputsBlockPartsStats(t *testing.T) { - configSetup(t) + config := configSetup(t) // create dummy peer - cs, _ := randState(1) + cs, _ := randState(config, 1) peer := p2pmock.NewPeer(nil) // 1) new block part @@ -1901,15 +1905,15 @@ func TestStateOutputsBlockPartsStats(t *testing.T) { } func TestStateOutputVoteStats(t *testing.T) { - configSetup(t) + config := configSetup(t) - cs, vss := randState(2) + cs, vss := randState(config, 2) // create dummy peer peer := p2pmock.NewPeer(nil) randBytes := tmrand.Bytes(tmhash.Size) - vote := signVote(vss[1], tmproto.PrecommitType, randBytes, types.PartSetHeader{}) + vote := signVote(vss[1], config, tmproto.PrecommitType, randBytes, types.PartSetHeader{}) voteMessage := &VoteMessage{vote} cs.handleMsg(msgInfo{voteMessage, peer.ID()}) @@ -1923,7 +1927,7 @@ func TestStateOutputVoteStats(t *testing.T) { // sending the vote for the bigger height incrementHeight(vss[1]) - vote = signVote(vss[1], tmproto.PrecommitType, randBytes, types.PartSetHeader{}) + vote = signVote(vss[1], config, tmproto.PrecommitType, randBytes, types.PartSetHeader{}) cs.handleMsg(msgInfo{&VoteMessage{vote}, peer.ID()})