mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-07 13:55:17 +00:00
consensus: reduce shared state in tests (#6313)
This commit is contained in:
@@ -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++ {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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++ {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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()})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user