Browse Source

tests: remove panics from test fixtures (#7522)

pull/7528/head
Sam Kleinman 3 years ago
committed by GitHub
parent
commit
569629486b
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 814 additions and 857 deletions
  1. +11
    -15
      cmd/tendermint/commands/root_test.go
  2. +1
    -1
      crypto/merkle/proof_key_path_test.go
  3. +43
    -33
      crypto/xchacha20poly1305/vector_test.go
  4. +2
    -2
      internal/consensus/byzantine_test.go
  5. +193
    -220
      internal/consensus/common_test.go
  6. +37
    -34
      internal/consensus/mempool_test.go
  7. +5
    -4
      internal/consensus/reactor_test.go
  8. +9
    -1
      internal/consensus/replay.go
  9. +10
    -5
      internal/consensus/replay_stubs.go
  10. +104
    -115
      internal/consensus/replay_test.go
  11. +304
    -335
      internal/consensus/state_test.go
  12. +5
    -4
      internal/consensus/types/height_vote_set_test.go
  13. +1
    -1
      internal/consensus/wal_test.go
  14. +1
    -3
      internal/evidence/verify_test.go
  15. +6
    -7
      internal/libs/protoio/io_test.go
  16. +5
    -6
      internal/libs/protoio/writer_test.go
  17. +5
    -5
      internal/state/execution_test.go
  18. +8
    -10
      internal/state/helpers_test.go
  19. +3
    -3
      internal/state/validation_test.go
  20. +14
    -7
      internal/store/store_test.go
  21. +2
    -4
      libs/bits/bit_array_test.go
  22. +6
    -7
      libs/cli/setup_test.go
  23. +3
    -3
      node/node_test.go
  24. +2
    -2
      rpc/client/event_test.go
  25. +17
    -18
      rpc/jsonrpc/client/ws_client_test.go
  26. +10
    -6
      rpc/jsonrpc/jsonrpc_test.go
  27. +7
    -6
      test/e2e/tests/validator_test.go

+ 11
- 15
cmd/tendermint/commands/root_test.go View File

@ -18,17 +18,12 @@ import (
) )
// clearConfig clears env vars, the given root dir, and resets viper. // clearConfig clears env vars, the given root dir, and resets viper.
func clearConfig(dir string) {
if err := os.Unsetenv("TMHOME"); err != nil {
panic(err)
}
if err := os.Unsetenv("TM_HOME"); err != nil {
panic(err)
}
func clearConfig(t *testing.T, dir string) {
t.Helper()
require.NoError(t, os.Unsetenv("TMHOME"))
require.NoError(t, os.Unsetenv("TM_HOME"))
require.NoError(t, os.RemoveAll(dir))
if err := os.RemoveAll(dir); err != nil {
panic(err)
}
viper.Reset() viper.Reset()
config = cfg.DefaultConfig() config = cfg.DefaultConfig()
} }
@ -46,8 +41,9 @@ func testRootCmd() *cobra.Command {
return rootCmd return rootCmd
} }
func testSetup(rootDir string, args []string, env map[string]string) error {
clearConfig(rootDir)
func testSetup(t *testing.T, rootDir string, args []string, env map[string]string) error {
t.Helper()
clearConfig(t, rootDir)
rootCmd := testRootCmd() rootCmd := testRootCmd()
cmd := cli.PrepareBaseCmd(rootCmd, "TM", rootDir) cmd := cli.PrepareBaseCmd(rootCmd, "TM", rootDir)
@ -73,7 +69,7 @@ func TestRootHome(t *testing.T) {
for i, tc := range cases { for i, tc := range cases {
idxString := strconv.Itoa(i) idxString := strconv.Itoa(i)
err := testSetup(defaultRoot, tc.args, tc.env)
err := testSetup(t, defaultRoot, tc.args, tc.env)
require.NoError(t, err, idxString) require.NoError(t, err, idxString)
assert.Equal(t, tc.root, config.RootDir, idxString) assert.Equal(t, tc.root, config.RootDir, idxString)
@ -105,7 +101,7 @@ func TestRootFlagsEnv(t *testing.T) {
for i, tc := range cases { for i, tc := range cases {
idxString := strconv.Itoa(i) idxString := strconv.Itoa(i)
err := testSetup(defaultRoot, tc.args, tc.env)
err := testSetup(t, defaultRoot, tc.args, tc.env)
require.NoError(t, err, idxString) require.NoError(t, err, idxString)
assert.Equal(t, tc.logLevel, config.LogLevel, idxString) assert.Equal(t, tc.logLevel, config.LogLevel, idxString)
@ -134,7 +130,7 @@ func TestRootConfig(t *testing.T) {
for i, tc := range cases { for i, tc := range cases {
defaultRoot := t.TempDir() defaultRoot := t.TempDir()
idxString := strconv.Itoa(i) idxString := strconv.Itoa(i)
clearConfig(defaultRoot)
clearConfig(t, defaultRoot)
// XXX: path must match cfg.defaultConfigPath // XXX: path must match cfg.defaultConfigPath
configFilePath := filepath.Join(defaultRoot, "config") configFilePath := filepath.Join(defaultRoot, "config")


+ 1
- 1
crypto/merkle/proof_key_path_test.go View File

@ -28,7 +28,7 @@ func TestKeyPath(t *testing.T) {
case KeyEncodingHex: case KeyEncodingHex:
rand.Read(keys[i]) rand.Read(keys[i])
default: default:
panic("Unexpected encoding")
require.Fail(t, "Unexpected encoding")
} }
path = path.AppendKey(keys[i], enc) path = path.AppendKey(keys[i], enc)
} }


+ 43
- 33
crypto/xchacha20poly1305/vector_test.go View File

@ -4,21 +4,61 @@ import (
"bytes" "bytes"
"encoding/hex" "encoding/hex"
"testing" "testing"
"github.com/stretchr/testify/require"
) )
func toHex(bits []byte) string { func toHex(bits []byte) string {
return hex.EncodeToString(bits) return hex.EncodeToString(bits)
} }
func fromHex(bits string) []byte {
func fromHex(bits string) ([]byte, error) {
b, err := hex.DecodeString(bits) b, err := hex.DecodeString(bits)
if err != nil { if err != nil {
panic(err)
return nil, err
} }
return b
return b, nil
}
func check(t *testing.T, fn func(string) ([]byte, error), hex string) []byte {
t.Helper()
res, err := fn(hex)
require.NoError(t, err)
return res
} }
func TestHChaCha20(t *testing.T) { func TestHChaCha20(t *testing.T) {
var hChaCha20Vectors = []struct {
key, nonce, keystream []byte
}{
{
check(t, fromHex, "0000000000000000000000000000000000000000000000000000000000000000"),
check(t, fromHex, "000000000000000000000000000000000000000000000000"),
check(t, fromHex, "1140704c328d1d5d0e30086cdf209dbd6a43b8f41518a11cc387b669b2ee6586"),
},
{
check(t, fromHex, "8000000000000000000000000000000000000000000000000000000000000000"),
check(t, fromHex, "000000000000000000000000000000000000000000000000"),
check(t, fromHex, "7d266a7fd808cae4c02a0a70dcbfbcc250dae65ce3eae7fc210f54cc8f77df86"),
},
{
check(t, fromHex, "0000000000000000000000000000000000000000000000000000000000000001"),
check(t, fromHex, "000000000000000000000000000000000000000000000002"),
check(t, fromHex, "e0c77ff931bb9163a5460c02ac281c2b53d792b1c43fea817e9ad275ae546963"),
},
{
check(t, fromHex, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"),
check(t, fromHex, "000102030405060708090a0b0c0d0e0f1011121314151617"),
check(t, fromHex, "51e3ff45a895675c4b33b46c64f4a9ace110d34df6a2ceab486372bacbd3eff6"),
},
{
check(t, fromHex, "24f11cce8a1b3d61e441561a696c1c1b7e173d084fd4812425435a8896a013dc"),
check(t, fromHex, "d9660c5900ae19ddad28d6e06e45fe5e"),
check(t, fromHex, "5966b3eec3bff1189f831f06afe4d4e3be97fa9235ec8c20d08acfbbb4e851e3"),
},
}
for i, v := range hChaCha20Vectors { for i, v := range hChaCha20Vectors {
var key [32]byte var key [32]byte
var nonce [16]byte var nonce [16]byte
@ -32,36 +72,6 @@ func TestHChaCha20(t *testing.T) {
} }
} }
var hChaCha20Vectors = []struct {
key, nonce, keystream []byte
}{
{
fromHex("0000000000000000000000000000000000000000000000000000000000000000"),
fromHex("000000000000000000000000000000000000000000000000"),
fromHex("1140704c328d1d5d0e30086cdf209dbd6a43b8f41518a11cc387b669b2ee6586"),
},
{
fromHex("8000000000000000000000000000000000000000000000000000000000000000"),
fromHex("000000000000000000000000000000000000000000000000"),
fromHex("7d266a7fd808cae4c02a0a70dcbfbcc250dae65ce3eae7fc210f54cc8f77df86"),
},
{
fromHex("0000000000000000000000000000000000000000000000000000000000000001"),
fromHex("000000000000000000000000000000000000000000000002"),
fromHex("e0c77ff931bb9163a5460c02ac281c2b53d792b1c43fea817e9ad275ae546963"),
},
{
fromHex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"),
fromHex("000102030405060708090a0b0c0d0e0f1011121314151617"),
fromHex("51e3ff45a895675c4b33b46c64f4a9ace110d34df6a2ceab486372bacbd3eff6"),
},
{
fromHex("24f11cce8a1b3d61e441561a696c1c1b7e173d084fd4812425435a8896a013dc"),
fromHex("d9660c5900ae19ddad28d6e06e45fe5e"),
fromHex("5966b3eec3bff1189f831f06afe4d4e3be97fa9235ec8c20d08acfbbb4e851e3"),
},
}
func TestVectors(t *testing.T) { func TestVectors(t *testing.T) {
for i, v := range vectors { for i, v := range vectors {
if len(v.plaintext) == 0 { if len(v.plaintext) == 0 {


+ 2
- 2
internal/consensus/byzantine_test.go View File

@ -58,8 +58,8 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
defer os.RemoveAll(thisConfig.RootDir) defer os.RemoveAll(thisConfig.RootDir)
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc()
ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc(t)
vals := types.TM2PB.ValidatorUpdates(state.Validators) vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})


+ 193
- 220
internal/consensus/common_test.go View File

@ -73,10 +73,9 @@ func configSetup(t *testing.T) *config.Config {
return cfg return cfg
} }
func ensureDir(dir string, mode os.FileMode) {
if err := tmos.EnsureDir(dir, mode); err != nil {
panic(err)
}
func ensureDir(t *testing.T, dir string, mode os.FileMode) {
t.Helper()
require.NoError(t, tmos.EnsureDir(dir, mode))
} }
func ResetConfig(name string) (*config.Config, error) { func ResetConfig(name string) (*config.Config, error) {
@ -147,6 +146,7 @@ func (vs *validatorStub) signVote(
// Sign vote for type/hash/header // Sign vote for type/hash/header
func signVote( func signVote(
ctx context.Context, ctx context.Context,
t *testing.T,
vs *validatorStub, vs *validatorStub,
cfg *config.Config, cfg *config.Config,
voteType tmproto.SignedMsgType, voteType tmproto.SignedMsgType,
@ -155,9 +155,7 @@ func signVote(
) *types.Vote { ) *types.Vote {
v, err := vs.signVote(ctx, cfg, voteType, hash, header) v, err := vs.signVote(ctx, cfg, voteType, hash, header)
if err != nil {
panic(fmt.Errorf("failed to sign vote: %w", err))
}
require.NoError(t, err, "failed to sign vote")
vs.lastVote = v vs.lastVote = v
@ -166,14 +164,16 @@ func signVote(
func signVotes( func signVotes(
ctx context.Context, ctx context.Context,
t *testing.T,
cfg *config.Config, cfg *config.Config,
voteType tmproto.SignedMsgType, voteType tmproto.SignedMsgType,
hash []byte, hash []byte,
header types.PartSetHeader, header types.PartSetHeader,
vss ...*validatorStub) []*types.Vote {
vss ...*validatorStub,
) []*types.Vote {
votes := make([]*types.Vote, len(vss)) votes := make([]*types.Vote, len(vss))
for i, vs := range vss { for i, vs := range vss {
votes[i] = signVote(ctx, vs, cfg, voteType, hash, header)
votes[i] = signVote(ctx, t, vs, cfg, voteType, hash, header)
} }
return votes return votes
} }
@ -196,16 +196,14 @@ func (vss ValidatorStubsByPower) Len() int {
return len(vss) return len(vss)
} }
func sortVValidatorStubsByPower(ctx context.Context, vss []*validatorStub) []*validatorStub {
func sortVValidatorStubsByPower(ctx context.Context, t *testing.T, vss []*validatorStub) []*validatorStub {
t.Helper()
sort.Slice(vss, func(i, j int) bool { sort.Slice(vss, func(i, j int) bool {
vssi, err := vss[i].GetPubKey(ctx) vssi, err := vss[i].GetPubKey(ctx)
if err != nil {
panic(err)
}
require.NoError(t, err)
vssj, err := vss[j].GetPubKey(ctx) vssj, err := vss[j].GetPubKey(ctx)
if err != nil {
panic(err)
}
require.NoError(t, err)
if vss[i].VotingPower == vss[j].VotingPower { if vss[i].VotingPower == vss[j].VotingPower {
return bytes.Compare(vssi.Address(), vssj.Address()) == -1 return bytes.Compare(vssi.Address(), vssj.Address()) == -1
@ -237,23 +235,22 @@ func decideProposal(
height int64, height int64,
round int32, round int32,
) (proposal *types.Proposal, block *types.Block) { ) (proposal *types.Proposal, block *types.Block) {
t.Helper()
cs1.mtx.Lock() cs1.mtx.Lock()
block, blockParts, err := cs1.createProposalBlock() block, blockParts, err := cs1.createProposalBlock()
require.NoError(t, err) require.NoError(t, err)
validRound := cs1.ValidRound validRound := cs1.ValidRound
chainID := cs1.state.ChainID chainID := cs1.state.ChainID
cs1.mtx.Unlock() cs1.mtx.Unlock()
if block == nil {
panic("Failed to createProposalBlock. Did you forget to add commit for previous block?")
}
require.NotNil(t, block, "Failed to createProposalBlock. Did you forget to add commit for previous block?")
// Make proposal // Make proposal
polRound, propBlockID := validRound, types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()} polRound, propBlockID := validRound, types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}
proposal = types.NewProposal(height, round, polRound, propBlockID) proposal = types.NewProposal(height, round, polRound, propBlockID)
p := proposal.ToProto() p := proposal.ToProto()
if err := vs.SignProposal(ctx, chainID, p); err != nil {
panic(err)
}
require.NoError(t, vs.SignProposal(ctx, chainID, p))
proposal.Signature = p.Signature proposal.Signature = p.Signature
@ -268,6 +265,7 @@ func addVotes(to *State, votes ...*types.Vote) {
func signAddVotes( func signAddVotes(
ctx context.Context, ctx context.Context,
t *testing.T,
cfg *config.Config, cfg *config.Config,
to *State, to *State,
voteType tmproto.SignedMsgType, voteType tmproto.SignedMsgType,
@ -275,7 +273,7 @@ func signAddVotes(
header types.PartSetHeader, header types.PartSetHeader,
vss ...*validatorStub, vss ...*validatorStub,
) { ) {
addVotes(to, signVotes(ctx, cfg, voteType, hash, header, vss...)...)
addVotes(to, signVotes(ctx, t, cfg, voteType, hash, header, vss...)...)
} }
func validatePrevote( func validatePrevote(
@ -286,37 +284,37 @@ func validatePrevote(
privVal *validatorStub, privVal *validatorStub,
blockHash []byte, blockHash []byte,
) { ) {
t.Helper()
prevotes := cs.Votes.Prevotes(round) prevotes := cs.Votes.Prevotes(round)
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
address := pubKey.Address() address := pubKey.Address()
var vote *types.Vote
if vote = prevotes.GetByAddress(address); vote == nil {
panic("Failed to find prevote from validator")
}
vote := prevotes.GetByAddress(address)
require.NotNil(t, vote, "Failed to find prevote from validator")
if blockHash == nil { if blockHash == nil {
if vote.BlockID.Hash != nil {
panic(fmt.Sprintf("Expected prevote to be for nil, got %X", vote.BlockID.Hash))
}
require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash)
} else { } else {
if !bytes.Equal(vote.BlockID.Hash, blockHash) {
panic(fmt.Sprintf("Expected prevote to be for %X, got %X", blockHash, vote.BlockID.Hash))
}
require.True(t, bytes.Equal(vote.BlockID.Hash, blockHash), "Expected prevote to be for %X, got %X", blockHash, vote.BlockID.Hash)
} }
} }
func validateLastPrecommit(ctx context.Context, t *testing.T, cs *State, privVal *validatorStub, blockHash []byte) { func validateLastPrecommit(ctx context.Context, t *testing.T, cs *State, privVal *validatorStub, blockHash []byte) {
t.Helper()
votes := cs.LastCommit votes := cs.LastCommit
pv, err := privVal.GetPubKey(ctx) pv, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
address := pv.Address() address := pv.Address()
var vote *types.Vote
if vote = votes.GetByAddress(address); vote == nil {
panic("Failed to find precommit from validator")
}
if !bytes.Equal(vote.BlockID.Hash, blockHash) {
panic(fmt.Sprintf("Expected precommit to be for %X, got %X", blockHash, vote.BlockID.Hash))
}
vote := votes.GetByAddress(address)
require.NotNil(t, vote)
require.True(t, bytes.Equal(vote.BlockID.Hash, blockHash),
"Expected precommit to be for %X, got %X", blockHash, vote.BlockID.Hash)
} }
func validatePrecommit( func validatePrecommit(
@ -329,42 +327,35 @@ func validatePrecommit(
votedBlockHash, votedBlockHash,
lockedBlockHash []byte, lockedBlockHash []byte,
) { ) {
t.Helper()
precommits := cs.Votes.Precommits(thisRound) precommits := cs.Votes.Precommits(thisRound)
pv, err := privVal.GetPubKey(ctx) pv, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
address := pv.Address() address := pv.Address()
var vote *types.Vote
if vote = precommits.GetByAddress(address); vote == nil {
panic("Failed to find precommit from validator")
}
vote := precommits.GetByAddress(address)
require.NotNil(t, vote, "Failed to find precommit from validator")
if votedBlockHash == nil { if votedBlockHash == nil {
if vote.BlockID.Hash != nil {
panic("Expected precommit to be for nil")
}
require.Nil(t, vote.BlockID.Hash, "Expected precommit to be for nil")
} else { } else {
if !bytes.Equal(vote.BlockID.Hash, votedBlockHash) {
panic("Expected precommit to be for proposal block")
}
require.True(t, bytes.Equal(vote.BlockID.Hash, votedBlockHash), "Expected precommit to be for proposal block")
} }
if lockedBlockHash == nil { if lockedBlockHash == nil {
if cs.LockedRound != lockRound || cs.LockedBlock != nil {
panic(fmt.Sprintf(
"Expected to be locked on nil at round %d. Got locked at round %d with block %v",
lockRound,
cs.LockedRound,
cs.LockedBlock))
}
require.False(t, cs.LockedRound != lockRound || cs.LockedBlock != nil,
"Expected to be locked on nil at round %d. Got locked at round %d with block %v",
lockRound,
cs.LockedRound,
cs.LockedBlock)
} else { } else {
if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) {
panic(fmt.Sprintf(
"Expected block to be locked on round %d, got %d. Got locked block %X, expected %X",
lockRound,
cs.LockedRound,
cs.LockedBlock.Hash(),
lockedBlockHash))
}
require.False(t, cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash),
"Expected block to be locked on round %d, got %d. Got locked block %X, expected %X",
lockRound,
cs.LockedRound,
cs.LockedBlock.Hash(),
lockedBlockHash)
} }
} }
@ -408,32 +399,36 @@ func subscribeToVoter(ctx context.Context, t *testing.T, cs *State, addr []byte)
func newState( func newState(
ctx context.Context, ctx context.Context,
t *testing.T,
logger log.Logger, logger log.Logger,
state sm.State, state sm.State,
pv types.PrivValidator, pv types.PrivValidator,
app abci.Application, app abci.Application,
) (*State, error) {
) *State {
t.Helper()
cfg, err := config.ResetTestRoot("consensus_state_test") cfg, err := config.ResetTestRoot("consensus_state_test")
if err != nil {
return nil, err
}
require.NoError(t, err)
return newStateWithConfig(ctx, logger, cfg, state, pv, app), nil
return newStateWithConfig(ctx, t, logger, cfg, state, pv, app)
} }
func newStateWithConfig( func newStateWithConfig(
ctx context.Context, ctx context.Context,
t *testing.T,
logger log.Logger, logger log.Logger,
thisConfig *config.Config, thisConfig *config.Config,
state sm.State, state sm.State,
pv types.PrivValidator, pv types.PrivValidator,
app abci.Application, app abci.Application,
) *State { ) *State {
return newStateWithConfigAndBlockStore(ctx, logger, thisConfig, state, pv, app, store.NewBlockStore(dbm.NewMemDB()))
t.Helper()
return newStateWithConfigAndBlockStore(ctx, t, logger, thisConfig, state, pv, app, store.NewBlockStore(dbm.NewMemDB()))
} }
func newStateWithConfigAndBlockStore( func newStateWithConfigAndBlockStore(
ctx context.Context, ctx context.Context,
t *testing.T,
logger log.Logger, logger log.Logger,
thisConfig *config.Config, thisConfig *config.Config,
state sm.State, state sm.State,
@ -441,6 +436,8 @@ func newStateWithConfigAndBlockStore(
app abci.Application, app abci.Application,
blockStore *store.BlockStore, blockStore *store.BlockStore,
) *State { ) *State {
t.Helper()
// one for mempool, one for consensus // one for mempool, one for consensus
mtx := new(sync.Mutex) mtx := new(sync.Mutex)
proxyAppConnMem := abciclient.NewLocalClient(logger, mtx, app) proxyAppConnMem := abciclient.NewLocalClient(logger, mtx, app)
@ -464,9 +461,7 @@ func newStateWithConfigAndBlockStore(
// Make State // Make State
stateDB := dbm.NewMemDB() stateDB := dbm.NewMemDB()
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
if err := stateStore.Save(state); err != nil { // for save height 1's validators info
panic(err)
}
require.NoError(t, stateStore.Save(state))
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyAppConnCon, mempool, evpool, blockStore) blockExec := sm.NewBlockExecutor(stateStore, logger, proxyAppConnCon, mempool, evpool, blockStore)
cs := NewState(ctx, cs := NewState(ctx,
@ -481,17 +476,16 @@ func newStateWithConfigAndBlockStore(
cs.SetPrivValidator(ctx, pv) cs.SetPrivValidator(ctx, pv)
eventBus := eventbus.NewDefault(logger.With("module", "events")) eventBus := eventbus.NewDefault(logger.With("module", "events"))
err := eventBus.Start(ctx)
if err != nil {
panic(err)
}
require.NoError(t, eventBus.Start(ctx))
cs.SetEventBus(eventBus) cs.SetEventBus(eventBus)
return cs return cs
} }
func loadPrivValidator(t *testing.T, cfg *config.Config) *privval.FilePV { func loadPrivValidator(t *testing.T, cfg *config.Config) *privval.FilePV {
t.Helper()
privValidatorKeyFile := cfg.PrivValidator.KeyFile() privValidatorKeyFile := cfg.PrivValidator.KeyFile()
ensureDir(filepath.Dir(privValidatorKeyFile), 0700)
ensureDir(t, filepath.Dir(privValidatorKeyFile), 0700)
privValidatorStateFile := cfg.PrivValidator.StateFile() privValidatorStateFile := cfg.PrivValidator.StateFile()
privValidator, err := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile) privValidator, err := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
require.NoError(t, err) require.NoError(t, err)
@ -505,16 +499,15 @@ func randState(
cfg *config.Config, cfg *config.Config,
logger log.Logger, logger log.Logger,
nValidators int, nValidators int,
) (*State, []*validatorStub, error) {
) (*State, []*validatorStub) {
t.Helper()
// Get State // Get State
state, privVals := randGenesisState(ctx, t, cfg, nValidators, false, 10) state, privVals := randGenesisState(ctx, t, cfg, nValidators, false, 10)
vss := make([]*validatorStub, nValidators) vss := make([]*validatorStub, nValidators)
cs, err := newState(ctx, logger, state, privVals[0], kvstore.NewApplication())
if err != nil {
return nil, nil, err
}
cs := newState(ctx, t, logger, state, privVals[0], kvstore.NewApplication())
for i := 0; i < nValidators; i++ { for i := 0; i < nValidators; i++ {
vss[i] = newValidatorStub(privVals[i], int32(i)) vss[i] = newValidatorStub(privVals[i], int32(i))
@ -522,225 +515,208 @@ func randState(
// since cs1 starts at 1 // since cs1 starts at 1
incrementHeight(vss[1:]...) incrementHeight(vss[1:]...)
return cs, vss, nil
return cs, vss
} }
//------------------------------------------------------------------------------- //-------------------------------------------------------------------------------
func ensureNoNewEvent(ch <-chan tmpubsub.Message, timeout time.Duration,
errorMessage string) {
func ensureNoNewEvent(t *testing.T, ch <-chan tmpubsub.Message, timeout time.Duration, errorMessage string) {
t.Helper()
select { select {
case <-time.After(timeout): case <-time.After(timeout):
break break
case <-ch: case <-ch:
panic(errorMessage)
t.Fatal(errorMessage)
} }
} }
func ensureNoNewEventOnChannel(ch <-chan tmpubsub.Message) {
ensureNoNewEvent(
func ensureNoNewEventOnChannel(t *testing.T, ch <-chan tmpubsub.Message) {
t.Helper()
ensureNoNewEvent(t,
ch, ch,
ensureTimeout, ensureTimeout,
"We should be stuck waiting, not receiving new event on the channel") "We should be stuck waiting, not receiving new event on the channel")
} }
func ensureNoNewRoundStep(stepCh <-chan tmpubsub.Message) {
func ensureNoNewRoundStep(t *testing.T, stepCh <-chan tmpubsub.Message) {
t.Helper()
ensureNoNewEvent( ensureNoNewEvent(
t,
stepCh, stepCh,
ensureTimeout, ensureTimeout,
"We should be stuck waiting, not receiving NewRoundStep event") "We should be stuck waiting, not receiving NewRoundStep event")
} }
func ensureNoNewUnlock(unlockCh <-chan tmpubsub.Message) {
ensureNoNewEvent(
func ensureNoNewUnlock(t *testing.T, unlockCh <-chan tmpubsub.Message) {
t.Helper()
ensureNoNewEvent(t,
unlockCh, unlockCh,
ensureTimeout, ensureTimeout,
"We should be stuck waiting, not receiving Unlock event") "We should be stuck waiting, not receiving Unlock event")
} }
func ensureNoNewTimeout(stepCh <-chan tmpubsub.Message, timeout int64) {
func ensureNoNewTimeout(t *testing.T, stepCh <-chan tmpubsub.Message, timeout int64) {
t.Helper()
timeoutDuration := time.Duration(timeout*10) * time.Nanosecond timeoutDuration := time.Duration(timeout*10) * time.Nanosecond
ensureNoNewEvent(
ensureNoNewEvent(t,
stepCh, stepCh,
timeoutDuration, timeoutDuration,
"We should be stuck waiting, not receiving NewTimeout event") "We should be stuck waiting, not receiving NewTimeout event")
} }
func ensureNewEvent(ch <-chan tmpubsub.Message, height int64, round int32, timeout time.Duration, errorMessage string) {
func ensureNewEvent(t *testing.T, ch <-chan tmpubsub.Message, height int64, round int32, timeout time.Duration, errorMessage string) {
t.Helper()
select { select {
case <-time.After(timeout): case <-time.After(timeout):
panic(errorMessage)
t.Fatal(errorMessage)
case msg := <-ch: case msg := <-ch:
roundStateEvent, ok := msg.Data().(types.EventDataRoundState) roundStateEvent, ok := msg.Data().(types.EventDataRoundState)
if !ok {
panic(fmt.Sprintf("expected a EventDataRoundState, got %T. Wrong subscription channel?",
msg.Data()))
}
if roundStateEvent.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, roundStateEvent.Height))
}
if roundStateEvent.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, roundStateEvent.Round))
}
require.True(t, ok,
"expected a EventDataRoundState, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, roundStateEvent.Height)
require.Equal(t, round, roundStateEvent.Round)
// TODO: We could check also for a step at this point! // TODO: We could check also for a step at this point!
} }
} }
func ensureNewRound(roundCh <-chan tmpubsub.Message, height int64, round int32) {
func ensureNewRound(t *testing.T, roundCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewRound event")
t.Fatal("Timeout expired while waiting for NewRound event")
case msg := <-roundCh: case msg := <-roundCh:
newRoundEvent, ok := msg.Data().(types.EventDataNewRound) newRoundEvent, ok := msg.Data().(types.EventDataNewRound)
if !ok {
panic(fmt.Sprintf("expected a EventDataNewRound, got %T. Wrong subscription channel?",
msg.Data()))
}
if newRoundEvent.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, newRoundEvent.Height))
}
if newRoundEvent.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, newRoundEvent.Round))
}
require.True(t, ok, "expected a EventDataNewRound, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, newRoundEvent.Height)
require.Equal(t, round, newRoundEvent.Round)
} }
} }
func ensureNewTimeout(timeoutCh <-chan tmpubsub.Message, height int64, round int32, timeout int64) {
func ensureNewTimeout(t *testing.T, timeoutCh <-chan tmpubsub.Message, height int64, round int32, timeout int64) {
t.Helper()
timeoutDuration := time.Duration(timeout*10) * time.Nanosecond timeoutDuration := time.Duration(timeout*10) * time.Nanosecond
ensureNewEvent(timeoutCh, height, round, timeoutDuration,
ensureNewEvent(t, timeoutCh, height, round, timeoutDuration,
"Timeout expired while waiting for NewTimeout event") "Timeout expired while waiting for NewTimeout event")
} }
func ensureNewProposal(proposalCh <-chan tmpubsub.Message, height int64, round int32) {
func ensureNewProposal(t *testing.T, proposalCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewProposal event")
t.Fatal("Timeout expired while waiting for NewProposal event")
case msg := <-proposalCh: case msg := <-proposalCh:
proposalEvent, ok := msg.Data().(types.EventDataCompleteProposal) proposalEvent, ok := msg.Data().(types.EventDataCompleteProposal)
if !ok {
panic(fmt.Sprintf("expected a EventDataCompleteProposal, got %T. Wrong subscription channel?",
msg.Data()))
}
if proposalEvent.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, proposalEvent.Height))
}
if proposalEvent.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, proposalEvent.Round))
}
require.True(t, ok, "expected a EventDataCompleteProposal, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, proposalEvent.Height)
require.Equal(t, round, proposalEvent.Round)
} }
} }
func ensureNewValidBlock(validBlockCh <-chan tmpubsub.Message, height int64, round int32) {
ensureNewEvent(validBlockCh, height, round, ensureTimeout,
func ensureNewValidBlock(t *testing.T, validBlockCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
ensureNewEvent(t, validBlockCh, height, round, ensureTimeout,
"Timeout expired while waiting for NewValidBlock event") "Timeout expired while waiting for NewValidBlock event")
} }
func ensureNewBlock(blockCh <-chan tmpubsub.Message, height int64) {
func ensureNewBlock(t *testing.T, blockCh <-chan tmpubsub.Message, height int64) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewBlock event")
t.Fatal("Timeout expired while waiting for NewBlock event")
case msg := <-blockCh: case msg := <-blockCh:
blockEvent, ok := msg.Data().(types.EventDataNewBlock) blockEvent, ok := msg.Data().(types.EventDataNewBlock)
if !ok {
panic(fmt.Sprintf("expected a EventDataNewBlock, got %T. Wrong subscription channel?",
msg.Data()))
}
if blockEvent.Block.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, blockEvent.Block.Height))
}
require.True(t, ok, "expected a EventDataNewBlock, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, blockEvent.Block.Height)
} }
} }
func ensureNewBlockHeader(blockCh <-chan tmpubsub.Message, height int64, blockHash tmbytes.HexBytes) {
func ensureNewBlockHeader(t *testing.T, blockCh <-chan tmpubsub.Message, height int64, blockHash tmbytes.HexBytes) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewBlockHeader event")
t.Fatal("Timeout expired while waiting for NewBlockHeader event")
case msg := <-blockCh: case msg := <-blockCh:
blockHeaderEvent, ok := msg.Data().(types.EventDataNewBlockHeader) blockHeaderEvent, ok := msg.Data().(types.EventDataNewBlockHeader)
if !ok {
panic(fmt.Sprintf("expected a EventDataNewBlockHeader, got %T. Wrong subscription channel?",
msg.Data()))
}
if blockHeaderEvent.Header.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, blockHeaderEvent.Header.Height))
}
if !bytes.Equal(blockHeaderEvent.Header.Hash(), blockHash) {
panic(fmt.Sprintf("expected header %X, got %X", blockHash, blockHeaderEvent.Header.Hash()))
}
require.True(t, ok, "expected a EventDataNewBlockHeader, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, blockHeaderEvent.Header.Height)
require.True(t, bytes.Equal(blockHeaderEvent.Header.Hash(), blockHash))
} }
} }
func ensureNewUnlock(unlockCh <-chan tmpubsub.Message, height int64, round int32) {
ensureNewEvent(unlockCh, height, round, ensureTimeout,
func ensureNewUnlock(t *testing.T, unlockCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
ensureNewEvent(t, unlockCh, height, round, ensureTimeout,
"Timeout expired while waiting for NewUnlock event") "Timeout expired while waiting for NewUnlock event")
} }
func ensureProposal(proposalCh <-chan tmpubsub.Message, height int64, round int32, propID types.BlockID) {
func ensureProposal(t *testing.T, proposalCh <-chan tmpubsub.Message, height int64, round int32, propID types.BlockID) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewProposal event")
t.Fatal("Timeout expired while waiting for NewProposal event")
case msg := <-proposalCh: case msg := <-proposalCh:
proposalEvent, ok := msg.Data().(types.EventDataCompleteProposal) proposalEvent, ok := msg.Data().(types.EventDataCompleteProposal)
if !ok {
panic(fmt.Sprintf("expected a EventDataCompleteProposal, got %T. Wrong subscription channel?",
msg.Data()))
}
if proposalEvent.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, proposalEvent.Height))
}
if proposalEvent.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, proposalEvent.Round))
}
if !proposalEvent.BlockID.Equals(propID) {
panic(fmt.Sprintf("Proposed block does not match expected block (%v != %v)", proposalEvent.BlockID, propID))
}
require.True(t, ok, "expected a EventDataCompleteProposal, got %T. Wrong subscription channel?",
msg.Data())
require.Equal(t, height, proposalEvent.Height)
require.Equal(t, round, proposalEvent.Round)
require.True(t, proposalEvent.BlockID.Equals(propID),
"Proposed block does not match expected block (%v != %v)", proposalEvent.BlockID, propID)
} }
} }
func ensurePrecommit(voteCh <-chan tmpubsub.Message, height int64, round int32) {
ensureVote(voteCh, height, round, tmproto.PrecommitType)
func ensurePrecommit(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
ensureVote(t, voteCh, height, round, tmproto.PrecommitType)
} }
func ensurePrevote(voteCh <-chan tmpubsub.Message, height int64, round int32) {
ensureVote(voteCh, height, round, tmproto.PrevoteType)
func ensurePrevote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32) {
t.Helper()
ensureVote(t, voteCh, height, round, tmproto.PrevoteType)
} }
func ensureVote(voteCh <-chan tmpubsub.Message, height int64, round int32,
voteType tmproto.SignedMsgType) {
func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, voteType tmproto.SignedMsgType) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for NewVote event")
t.Fatal("Timeout expired while waiting for NewVote event")
case msg := <-voteCh: case msg := <-voteCh:
voteEvent, ok := msg.Data().(types.EventDataVote) voteEvent, ok := msg.Data().(types.EventDataVote)
if !ok {
panic(fmt.Sprintf("expected a EventDataVote, got %T. Wrong subscription channel?",
msg.Data()))
}
require.True(t, ok, "expected a EventDataVote, got %T. Wrong subscription channel?",
msg.Data())
vote := voteEvent.Vote vote := voteEvent.Vote
if vote.Height != height {
panic(fmt.Sprintf("expected height %v, got %v", height, vote.Height))
}
if vote.Round != round {
panic(fmt.Sprintf("expected round %v, got %v", round, vote.Round))
}
if vote.Type != voteType {
panic(fmt.Sprintf("expected type %v, got %v", voteType, vote.Type))
}
require.Equal(t, height, vote.Height)
require.Equal(t, round, vote.Round)
require.Equal(t, voteType, vote.Type)
} }
} }
func ensurePrecommitTimeout(ch <-chan tmpubsub.Message) {
func ensurePrecommitTimeout(t *testing.T, ch <-chan tmpubsub.Message) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for the Precommit to Timeout")
t.Fatal("Timeout expired while waiting for the Precommit to Timeout")
case <-ch: case <-ch:
} }
} }
func ensureNewEventOnChannel(ch <-chan tmpubsub.Message) {
func ensureNewEventOnChannel(t *testing.T, ch <-chan tmpubsub.Message) {
t.Helper()
select { select {
case <-time.After(ensureTimeout): case <-time.After(ensureTimeout):
panic("Timeout expired while waiting for new activity on the channel")
t.Fatal("Timeout expired while waiting for new activity on the channel")
case <-ch: case <-ch:
} }
} }
@ -761,7 +737,7 @@ func randConsensusState(
nValidators int, nValidators int,
testName string, testName string,
tickerFunc func() TimeoutTicker, tickerFunc func() TimeoutTicker,
appFunc func() abci.Application,
appFunc func(t *testing.T) abci.Application,
configOpts ...func(*config.Config), configOpts ...func(*config.Config),
) ([]*State, cleanupFunc) { ) ([]*State, cleanupFunc) {
@ -786,9 +762,9 @@ func randConsensusState(
opt(thisConfig) opt(thisConfig)
} }
ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
ensureDir(t, filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc()
app := appFunc(t)
if appCloser, ok := app.(io.Closer); ok { if appCloser, ok := app.(io.Closer); ok {
closeFuncs = append(closeFuncs, appCloser.Close) closeFuncs = append(closeFuncs, appCloser.Close)
@ -798,7 +774,7 @@ func randConsensusState(
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
l := logger.With("validator", i, "module", "consensus") l := logger.With("validator", i, "module", "consensus")
css[i] = newStateWithConfigAndBlockStore(ctx, l, thisConfig, state, privVals[i], app, blockStore)
css[i] = newStateWithConfigAndBlockStore(ctx, t, l, thisConfig, state, privVals[i], app, blockStore)
css[i].SetTimeoutTicker(tickerFunc()) css[i].SetTimeoutTicker(tickerFunc())
} }
@ -815,6 +791,7 @@ func randConsensusState(
// nPeers = nValidators + nNotValidator // nPeers = nValidators + nNotValidator
func randConsensusNetWithPeers( func randConsensusNetWithPeers(
ctx context.Context, ctx context.Context,
t *testing.T,
cfg *config.Config, cfg *config.Config,
nValidators int, nValidators int,
nPeers int, nPeers int,
@ -822,6 +799,8 @@ func randConsensusNetWithPeers(
tickerFunc func() TimeoutTicker, tickerFunc func() TimeoutTicker,
appFunc func(string) abci.Application, appFunc func(string) abci.Application,
) ([]*State, *types.GenesisDoc, *config.Config, cleanupFunc) { ) ([]*State, *types.GenesisDoc, *config.Config, cleanupFunc) {
t.Helper()
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, nValidators, false, testMinPower) genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, nValidators, false, testMinPower)
css := make([]*State, nPeers) css := make([]*State, nPeers)
logger := consensusLogger() logger := consensusLogger()
@ -831,12 +810,10 @@ func randConsensusNetWithPeers(
for i := 0; i < nPeers; i++ { for i := 0; i < nPeers; i++ {
state, _ := sm.MakeGenesisState(genDoc) state, _ := sm.MakeGenesisState(genDoc)
thisConfig, err := ResetConfig(fmt.Sprintf("%s_%d", testName, i)) thisConfig, err := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
if err != nil {
panic(err)
}
require.NoError(t, err)
configRootDirs = append(configRootDirs, thisConfig.RootDir) configRootDirs = append(configRootDirs, thisConfig.RootDir)
ensureDir(filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
ensureDir(t, filepath.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
if i == 0 { if i == 0 {
peer0Config = thisConfig peer0Config = thisConfig
} }
@ -845,18 +822,13 @@ func randConsensusNetWithPeers(
privVal = privVals[i] privVal = privVals[i]
} else { } else {
tempKeyFile, err := os.CreateTemp("", "priv_validator_key_") tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
if err != nil {
panic(err)
}
require.NoError(t, err)
tempStateFile, err := os.CreateTemp("", "priv_validator_state_") tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
if err != nil {
panic(err)
}
require.NoError(t, err)
privVal, err = privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "") privVal, err = privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
if err != nil {
panic(err)
}
require.NoError(t, err)
} }
app := appFunc(path.Join(cfg.DBDir(), fmt.Sprintf("%s_%d", testName, i))) app := appFunc(path.Join(cfg.DBDir(), fmt.Sprintf("%s_%d", testName, i)))
@ -868,7 +840,7 @@ func randConsensusNetWithPeers(
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
// sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above // sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above
css[i] = newStateWithConfig(ctx, logger.With("validator", i, "module", "consensus"), thisConfig, state, privVal, app)
css[i] = newStateWithConfig(ctx, t, logger.With("validator", i, "module", "consensus"), thisConfig, state, privVal, app)
css[i].SetTimeoutTicker(tickerFunc()) css[i].SetTimeoutTicker(tickerFunc())
} }
return css, genDoc, peer0Config, func() { return css, genDoc, peer0Config, func() {
@ -940,15 +912,16 @@ func (m *mockTicker) Chan() <-chan timeoutInfo {
func (*mockTicker) SetLogger(log.Logger) {} func (*mockTicker) SetLogger(log.Logger) {}
func newPersistentKVStore() abci.Application {
func newPersistentKVStore(t *testing.T) abci.Application {
t.Helper()
dir, err := os.MkdirTemp("", "persistent-kvstore") dir, err := os.MkdirTemp("", "persistent-kvstore")
if err != nil {
panic(err)
}
require.NoError(t, err)
return kvstore.NewPersistentKVStoreApplication(dir) return kvstore.NewPersistentKVStoreApplication(dir)
} }
func newKVStore() abci.Application {
func newKVStore(_ *testing.T) abci.Application {
return kvstore.NewApplication() return kvstore.NewApplication()
} }


+ 37
- 34
internal/consensus/mempool_test.go View File

@ -22,8 +22,11 @@ import (
) )
// for testing // for testing
func assertMempool(txn txNotifier) mempool.Mempool {
return txn.(mempool.Mempool)
func assertMempool(t *testing.T, txn txNotifier) mempool.Mempool {
t.Helper()
mp, ok := txn.(mempool.Mempool)
require.True(t, ok)
return mp
} }
func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) { func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) {
@ -38,18 +41,18 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) {
config.Consensus.CreateEmptyBlocks = false config.Consensus.CreateEmptyBlocks = false
state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10) state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10)
cs := newStateWithConfig(ctx, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
assertMempool(cs.txNotifier).EnableTxsAvailable()
cs := newStateWithConfig(ctx, t, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
assertMempool(t, cs.txNotifier).EnableTxsAvailable()
height, round := cs.Height, cs.Round height, round := cs.Height, cs.Round
newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock) newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock)
startTestRound(ctx, cs, height, round) startTestRound(ctx, cs, height, round)
ensureNewEventOnChannel(newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(newBlockCh)
deliverTxsRange(ctx, cs, 0, 1)
ensureNewEventOnChannel(newBlockCh) // commit txs
ensureNewEventOnChannel(newBlockCh) // commit updated app hash
ensureNoNewEventOnChannel(newBlockCh)
ensureNewEventOnChannel(t, newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(t, newBlockCh)
deliverTxsRange(ctx, t, cs, 0, 1)
ensureNewEventOnChannel(t, newBlockCh) // commit txs
ensureNewEventOnChannel(t, newBlockCh) // commit updated app hash
ensureNoNewEventOnChannel(t, newBlockCh)
} }
func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) { func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) {
@ -63,16 +66,16 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) {
config.Consensus.CreateEmptyBlocksInterval = ensureTimeout config.Consensus.CreateEmptyBlocksInterval = ensureTimeout
state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10) state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10)
cs := newStateWithConfig(ctx, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
cs := newStateWithConfig(ctx, t, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
assertMempool(cs.txNotifier).EnableTxsAvailable()
assertMempool(t, cs.txNotifier).EnableTxsAvailable()
newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock) newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock)
startTestRound(ctx, cs, cs.Height, cs.Round) startTestRound(ctx, cs, cs.Height, cs.Round)
ensureNewEventOnChannel(newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(newBlockCh) // then we dont make a block ...
ensureNewEventOnChannel(newBlockCh) // until the CreateEmptyBlocksInterval has passed
ensureNewEventOnChannel(t, newBlockCh) // first block gets committed
ensureNoNewEventOnChannel(t, newBlockCh) // then we dont make a block ...
ensureNewEventOnChannel(t, newBlockCh) // until the CreateEmptyBlocksInterval has passed
} }
func TestMempoolProgressInHigherRound(t *testing.T) { func TestMempoolProgressInHigherRound(t *testing.T) {
@ -86,8 +89,8 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
config.Consensus.CreateEmptyBlocks = false config.Consensus.CreateEmptyBlocks = false
state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10) state, privVals := randGenesisState(ctx, t, baseConfig, 1, false, 10)
cs := newStateWithConfig(ctx, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
assertMempool(cs.txNotifier).EnableTxsAvailable()
cs := newStateWithConfig(ctx, t, log.TestingLogger(), config, state, privVals[0], NewCounterApplication())
assertMempool(t, cs.txNotifier).EnableTxsAvailable()
height, round := cs.Height, cs.Round height, round := cs.Height, cs.Round
newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock) newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock)
newRoundCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewRound) newRoundCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewRound)
@ -103,30 +106,29 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
} }
startTestRound(ctx, cs, height, round) startTestRound(ctx, cs, height, round)
ensureNewRound(newRoundCh, height, round) // first round at first height
ensureNewEventOnChannel(newBlockCh) // first block gets committed
ensureNewRound(t, newRoundCh, height, round) // first round at first height
ensureNewEventOnChannel(t, newBlockCh) // first block gets committed
height++ // moving to the next height height++ // moving to the next height
round = 0 round = 0
ensureNewRound(newRoundCh, height, round) // first round at next height
deliverTxsRange(ctx, cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round
ensureNewTimeout(timeoutCh, height, round, cs.config.TimeoutPropose.Nanoseconds())
ensureNewRound(t, newRoundCh, height, round) // first round at next height
deliverTxsRange(ctx, t, cs, 0, 1) // we deliver txs, but dont set a proposal so we get the next round
ensureNewTimeout(t, timeoutCh, height, round, cs.config.TimeoutPropose.Nanoseconds())
round++ // moving to the next round
ensureNewRound(newRoundCh, height, round) // wait for the next round
ensureNewEventOnChannel(newBlockCh) // now we can commit the block
round++ // moving to the next round
ensureNewRound(t, newRoundCh, height, round) // wait for the next round
ensureNewEventOnChannel(t, newBlockCh) // now we can commit the block
} }
func deliverTxsRange(ctx context.Context, cs *State, start, end int) {
func deliverTxsRange(ctx context.Context, t *testing.T, cs *State, start, end int) {
t.Helper()
// Deliver some txs. // Deliver some txs.
for i := start; i < end; i++ { for i := start; i < end; i++ {
txBytes := make([]byte, 8) txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i)) binary.BigEndian.PutUint64(txBytes, uint64(i))
err := assertMempool(cs.txNotifier).CheckTx(ctx, txBytes, nil, mempool.TxInfo{})
if err != nil {
panic(fmt.Errorf("error after CheckTx: %w", err))
}
err := assertMempool(t, cs.txNotifier).CheckTx(ctx, txBytes, nil, mempool.TxInfo{})
require.NoError(t, err, "error after checkTx")
} }
} }
@ -142,6 +144,7 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) {
cs := newStateWithConfigAndBlockStore( cs := newStateWithConfigAndBlockStore(
ctx, ctx,
t,
logger, config, state, privVals[0], NewCounterApplication(), blockStore) logger, config, state, privVals[0], NewCounterApplication(), blockStore)
err := stateStore.Save(state) err := stateStore.Save(state)
@ -149,7 +152,7 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) {
newBlockHeaderCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlockHeader) newBlockHeaderCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlockHeader)
const numTxs int64 = 3000 const numTxs int64 = 3000
go deliverTxsRange(ctx, cs, 0, int(numTxs))
go deliverTxsRange(ctx, t, cs, 0, int(numTxs))
startTestRound(ctx, cs, cs.Height, cs.Round) startTestRound(ctx, cs, cs.Height, cs.Round)
for n := int64(0); n < numTxs; { for n := int64(0); n < numTxs; {
@ -172,7 +175,7 @@ func TestMempoolRmBadTx(t *testing.T) {
app := NewCounterApplication() app := NewCounterApplication()
stateStore := sm.NewStore(dbm.NewMemDB()) stateStore := sm.NewStore(dbm.NewMemDB())
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
cs := newStateWithConfigAndBlockStore(ctx, log.TestingLogger(), config, state, privVals[0], app, blockStore)
cs := newStateWithConfigAndBlockStore(ctx, t, log.TestingLogger(), config, state, privVals[0], app, blockStore)
err := stateStore.Save(state) err := stateStore.Save(state)
require.NoError(t, err) require.NoError(t, err)
@ -192,7 +195,7 @@ func TestMempoolRmBadTx(t *testing.T) {
// Try to send the tx through the mempool. // Try to send the tx through the mempool.
// CheckTx should not err, but the app should return a bad abci code // CheckTx should not err, but the app should return a bad abci code
// and the tx should get removed from the pool // and the tx should get removed from the pool
err := assertMempool(cs.txNotifier).CheckTx(ctx, txBytes, func(r *abci.Response) {
err := assertMempool(t, cs.txNotifier).CheckTx(ctx, txBytes, func(r *abci.Response) {
if r.GetCheckTx().Code != code.CodeTypeBadNonce { if r.GetCheckTx().Code != code.CodeTypeBadNonce {
t.Errorf("expected checktx to return bad nonce, got %v", r) t.Errorf("expected checktx to return bad nonce, got %v", r)
return return
@ -206,7 +209,7 @@ func TestMempoolRmBadTx(t *testing.T) {
// check for the tx // check for the tx
for { for {
txs := assertMempool(cs.txNotifier).ReapMaxBytesMaxGas(int64(len(txBytes)), -1)
txs := assertMempool(t, cs.txNotifier).ReapMaxBytesMaxGas(int64(len(txBytes)), -1)
if len(txs) == 0 { if len(txs) == 0 {
emptyMempoolCh <- struct{}{} emptyMempoolCh <- struct{}{}
return return


+ 5
- 4
internal/consensus/reactor_test.go View File

@ -184,7 +184,7 @@ func waitForAndValidateBlock(
require.NoError(t, validateBlock(newBlock, activeVals)) require.NoError(t, validateBlock(newBlock, activeVals))
for _, tx := range txs { for _, tx := range txs {
require.NoError(t, assertMempool(states[j].txNotifier).CheckTx(ctx, tx, nil, mempool.TxInfo{}))
require.NoError(t, assertMempool(t, states[j].txNotifier).CheckTx(ctx, tx, nil, mempool.TxInfo{}))
} }
} }
@ -381,8 +381,8 @@ func TestReactorWithEvidence(t *testing.T) {
defer os.RemoveAll(thisConfig.RootDir) defer os.RemoveAll(thisConfig.RootDir)
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc()
ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
app := appFunc(t)
vals := types.TM2PB.ValidatorUpdates(state.Validators) vals := types.TM2PB.ValidatorUpdates(state.Validators)
app.InitChain(abci.RequestInitChain{Validators: vals}) app.InitChain(abci.RequestInitChain{Validators: vals})
@ -495,7 +495,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) {
// send a tx // send a tx
require.NoError( require.NoError(
t, t,
assertMempool(states[3].txNotifier).CheckTx(
assertMempool(t, states[3].txNotifier).CheckTx(
ctx, ctx,
[]byte{1, 2, 3}, []byte{1, 2, 3},
nil, nil,
@ -703,6 +703,7 @@ func TestReactorValidatorSetChanges(t *testing.T) {
nVals := 4 nVals := 4
states, _, _, cleanup := randConsensusNetWithPeers( states, _, _, cleanup := randConsensusNetWithPeers(
ctx, ctx,
t,
cfg, cfg,
nVals, nVals,
nPeers, nPeers,


+ 9
- 1
internal/consensus/replay.go View File

@ -422,9 +422,17 @@ func (h *Handshaker) ReplayBlocks(
if err != nil { if err != nil {
return nil, err return nil, err
} }
mockApp := newMockProxyApp(ctx, h.logger, appHash, abciResponses)
mockApp, err := newMockProxyApp(ctx, h.logger, appHash, abciResponses)
if err != nil {
return nil, err
}
h.logger.Info("Replay last block using mock app") h.logger.Info("Replay last block using mock app")
state, err = h.replayBlock(ctx, state, storeBlockHeight, mockApp) state, err = h.replayBlock(ctx, state, storeBlockHeight, mockApp)
if err != nil {
return nil, err
}
return state.AppHash, err return state.AppHash, err
} }


+ 10
- 5
internal/consensus/replay_stubs.go View File

@ -61,17 +61,22 @@ func newMockProxyApp(
logger log.Logger, logger log.Logger,
appHash []byte, appHash []byte,
abciResponses *tmstate.ABCIResponses, abciResponses *tmstate.ABCIResponses,
) proxy.AppConnConsensus {
) (proxy.AppConnConsensus, error) {
clientCreator := abciclient.NewLocalCreator(&mockProxyApp{ clientCreator := abciclient.NewLocalCreator(&mockProxyApp{
appHash: appHash, appHash: appHash,
abciResponses: abciResponses, abciResponses: abciResponses,
}) })
cli, _ := clientCreator(logger)
err := cli.Start(ctx)
cli, err := clientCreator(logger)
if err != nil { if err != nil {
panic(err)
return nil, err
}
if err = cli.Start(ctx); err != nil {
return nil, err
} }
return proxy.NewAppConnConsensus(cli, proxy.NopMetrics())
return proxy.NewAppConnConsensus(cli, proxy.NopMetrics()), nil
} }
type mockProxyApp struct { type mockProxyApp struct {


+ 104
- 115
internal/consensus/replay_test.go View File

@ -64,6 +64,7 @@ func startNewStateAndWaitForBlock(ctx context.Context, t *testing.T, consensusRe
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
cs := newStateWithConfigAndBlockStore( cs := newStateWithConfigAndBlockStore(
ctx, ctx,
t,
logger, logger,
consensusReplayConfig, consensusReplayConfig,
state, state,
@ -102,16 +103,17 @@ func startNewStateAndWaitForBlock(ctx context.Context, t *testing.T, consensusRe
} }
} }
func sendTxs(ctx context.Context, cs *State) {
func sendTxs(ctx context.Context, t *testing.T, cs *State) {
t.Helper()
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
default: default:
tx := []byte{byte(i)} tx := []byte{byte(i)}
if err := assertMempool(cs.txNotifier).CheckTx(ctx, tx, nil, mempool.TxInfo{}); err != nil {
panic(err)
}
require.NoError(t, assertMempool(t, cs.txNotifier).CheckTx(ctx, tx, nil, mempool.TxInfo{}))
i++ i++
} }
} }
@ -132,7 +134,7 @@ func TestWALCrash(t *testing.T) {
1}, 1},
{"many non-empty blocks", {"many non-empty blocks",
func(stateDB dbm.DB, cs *State, ctx context.Context) { func(stateDB dbm.DB, cs *State, ctx context.Context) {
go sendTxs(ctx, cs)
go sendTxs(ctx, t, cs)
}, },
3}, 3},
} }
@ -168,6 +170,7 @@ LOOP:
privValidator := loadPrivValidator(t, consensusReplayConfig) privValidator := loadPrivValidator(t, consensusReplayConfig)
cs := newStateWithConfigAndBlockStore( cs := newStateWithConfigAndBlockStore(
rctx, rctx,
t,
logger, logger,
consensusReplayConfig, consensusReplayConfig,
state, state,
@ -334,6 +337,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
css, genDoc, cfg, cleanup := randConsensusNetWithPeers( css, genDoc, cfg, cleanup := randConsensusNetWithPeers(
ctx, ctx,
t,
cfg, cfg,
nVals, nVals,
nPeers, nPeers,
@ -361,15 +365,15 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
// start the machine // start the machine
startTestRound(ctx, css[0], height, round) startTestRound(ctx, css[0], height, round)
incrementHeight(vss...) incrementHeight(vss...)
ensureNewRound(newRoundCh, height, 0)
ensureNewProposal(proposalCh, height, round)
ensureNewRound(t, newRoundCh, height, 0)
ensureNewProposal(t, proposalCh, height, round)
rs := css[0].GetRoundState() rs := css[0].GetRoundState()
signAddVotes(ctx, sim.Config, css[0], tmproto.PrecommitType,
signAddVotes(ctx, t, sim.Config, css[0], tmproto.PrecommitType,
rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(),
vss[1:nVals]...) vss[1:nVals]...)
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
// HEIGHT 2 // HEIGHT 2
height++ height++
@ -379,7 +383,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
valPubKey1ABCI, err := encoding.PubKeyToProto(newValidatorPubKey1) valPubKey1ABCI, err := encoding.PubKeyToProto(newValidatorPubKey1)
require.NoError(t, err) require.NoError(t, err)
newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower) newValidatorTx1 := kvstore.MakeValSetChangeTx(valPubKey1ABCI, testMinPower)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx1, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
propBlock, _, err := css[0].createProposalBlock() // changeProposer(t, cs1, vs2) propBlock, _, err := css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err) require.NoError(t, err)
@ -398,12 +402,12 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
ensureNewProposal(proposalCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs = css[0].GetRoundState() rs = css[0].GetRoundState()
signAddVotes(ctx, sim.Config, css[0], tmproto.PrecommitType,
signAddVotes(ctx, t, sim.Config, css[0], tmproto.PrecommitType,
rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(),
vss[1:nVals]...) vss[1:nVals]...)
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
// HEIGHT 3 // HEIGHT 3
height++ height++
@ -413,7 +417,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1) updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1)
require.NoError(t, err) require.NoError(t, err)
updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25) updateValidatorTx1 := kvstore.MakeValSetChangeTx(updatePubKey1ABCI, 25)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, updateValidatorTx1, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err) require.NoError(t, err)
@ -432,12 +436,12 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
ensureNewProposal(proposalCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs = css[0].GetRoundState() rs = css[0].GetRoundState()
signAddVotes(ctx, sim.Config, css[0], tmproto.PrecommitType,
signAddVotes(ctx, t, sim.Config, css[0], tmproto.PrecommitType,
rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(), rs.ProposalBlock.Hash(), rs.ProposalBlockParts.Header(),
vss[1:nVals]...) vss[1:nVals]...)
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
// HEIGHT 4 // HEIGHT 4
height++ height++
@ -447,14 +451,14 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
newVal2ABCI, err := encoding.PubKeyToProto(newValidatorPubKey2) newVal2ABCI, err := encoding.PubKeyToProto(newValidatorPubKey2)
require.NoError(t, err) require.NoError(t, err)
newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower) newValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, testMinPower)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx2, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx2, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey(ctx) newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
newVal3ABCI, err := encoding.PubKeyToProto(newValidatorPubKey3) newVal3ABCI, err := encoding.PubKeyToProto(newValidatorPubKey3)
require.NoError(t, err) require.NoError(t, err)
newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower) newValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, testMinPower)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, newValidatorTx3, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err) require.NoError(t, err)
@ -463,7 +467,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
newVss := make([]*validatorStub, nVals+1) newVss := make([]*validatorStub, nVals+1)
copy(newVss, vss[:nVals+1]) copy(newVss, vss[:nVals+1])
newVss = sortVValidatorStubsByPower(ctx, newVss)
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
valIndexFn := func(cssIdx int) int { valIndexFn := func(cssIdx int) int {
for i, vs := range newVss { for i, vs := range newVss {
@ -477,10 +481,12 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
return i return i
} }
} }
panic(fmt.Sprintf("validator css[%d] not found in newVss", cssIdx))
t.Fatalf("validator css[%d] not found in newVss", cssIdx)
return -1
} }
selfIndex := valIndexFn(0) selfIndex := valIndexFn(0)
require.NotEqual(t, -1, selfIndex)
proposal = types.NewProposal(vss[3].Height, round, -1, blockID) proposal = types.NewProposal(vss[3].Height, round, -1, blockID)
p = proposal.ToProto() p = proposal.ToProto()
@ -493,10 +499,10 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
ensureNewProposal(proposalCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0) removeValidatorTx2 := kvstore.MakeValSetChangeTx(newVal2ABCI, 0)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, removeValidatorTx2, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, removeValidatorTx2, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
rs = css[0].GetRoundState() rs = css[0].GetRoundState()
@ -504,38 +510,41 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
if i == selfIndex { if i == selfIndex {
continue continue
} }
signAddVotes(ctx, sim.Config, css[0],
signAddVotes(ctx, t, sim.Config, css[0],
tmproto.PrecommitType, rs.ProposalBlock.Hash(), tmproto.PrecommitType, rs.ProposalBlock.Hash(),
rs.ProposalBlockParts.Header(), newVss[i]) rs.ProposalBlockParts.Header(), newVss[i])
} }
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
// HEIGHT 5 // HEIGHT 5
height++ height++
incrementHeight(vss...) incrementHeight(vss...)
// Reflect the changes to vss[nVals] at height 3 and resort newVss. // Reflect the changes to vss[nVals] at height 3 and resort newVss.
newVssIdx := valIndexFn(nVals) newVssIdx := valIndexFn(nVals)
require.NotEqual(t, -1, newVssIdx)
newVss[newVssIdx].VotingPower = 25 newVss[newVssIdx].VotingPower = 25
newVss = sortVValidatorStubsByPower(ctx, newVss)
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
selfIndex = valIndexFn(0) selfIndex = valIndexFn(0)
ensureNewProposal(proposalCh, height, round)
require.NotEqual(t, -1, selfIndex)
ensureNewProposal(t, proposalCh, height, round)
rs = css[0].GetRoundState() rs = css[0].GetRoundState()
for i := 0; i < nVals+1; i++ { for i := 0; i < nVals+1; i++ {
if i == selfIndex { if i == selfIndex {
continue continue
} }
signAddVotes(ctx, sim.Config, css[0],
signAddVotes(ctx, t, sim.Config, css[0],
tmproto.PrecommitType, rs.ProposalBlock.Hash(), tmproto.PrecommitType, rs.ProposalBlock.Hash(),
rs.ProposalBlockParts.Header(), newVss[i]) rs.ProposalBlockParts.Header(), newVss[i])
} }
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
// HEIGHT 6 // HEIGHT 6
height++ height++
incrementHeight(vss...) incrementHeight(vss...)
removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0) removeValidatorTx3 := kvstore.MakeValSetChangeTx(newVal3ABCI, 0)
err = assertMempool(css[0].txNotifier).CheckTx(ctx, removeValidatorTx3, nil, mempool.TxInfo{})
err = assertMempool(t, css[0].txNotifier).CheckTx(ctx, removeValidatorTx3, nil, mempool.TxInfo{})
assert.NoError(t, err) assert.NoError(t, err)
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2) propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
require.NoError(t, err) require.NoError(t, err)
@ -544,9 +553,11 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()} blockID = types.BlockID{Hash: propBlock.Hash(), PartSetHeader: propBlockParts.Header()}
newVss = make([]*validatorStub, nVals+3) newVss = make([]*validatorStub, nVals+3)
copy(newVss, vss[:nVals+3]) copy(newVss, vss[:nVals+3])
newVss = sortVValidatorStubsByPower(ctx, newVss)
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
selfIndex = valIndexFn(0) selfIndex = valIndexFn(0)
require.NotEqual(t, -1, selfIndex)
proposal = types.NewProposal(vss[1].Height, round, -1, blockID) proposal = types.NewProposal(vss[1].Height, round, -1, blockID)
p = proposal.ToProto() p = proposal.ToProto()
if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil { if err := vss[1].SignProposal(ctx, cfg.ChainID(), p); err != nil {
@ -558,17 +569,17 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil { if err := css[0].SetProposalAndBlock(ctx, proposal, propBlock, propBlockParts, "some peer"); err != nil {
t.Fatal(err) t.Fatal(err)
} }
ensureNewProposal(proposalCh, height, round)
ensureNewProposal(t, proposalCh, height, round)
rs = css[0].GetRoundState() rs = css[0].GetRoundState()
for i := 0; i < nVals+3; i++ { for i := 0; i < nVals+3; i++ {
if i == selfIndex { if i == selfIndex {
continue continue
} }
signAddVotes(ctx, sim.Config, css[0],
signAddVotes(ctx, t, sim.Config, css[0],
tmproto.PrecommitType, rs.ProposalBlock.Hash(), tmproto.PrecommitType, rs.ProposalBlock.Hash(),
rs.ProposalBlockParts.Header(), newVss[i]) rs.ProposalBlockParts.Header(), newVss[i])
} }
ensureNewRound(newRoundCh, height+1, 0)
ensureNewRound(t, newRoundCh, height+1, 0)
sim.Chain = make([]*types.Block, 0) sim.Chain = make([]*types.Block, 0)
sim.Commits = make([]*types.Commit, 0) sim.Commits = make([]*types.Commit, 0)
@ -670,7 +681,8 @@ func TestMockProxyApp(t *testing.T) {
err = proto.Unmarshal(bytes, loadedAbciRes) err = proto.Unmarshal(bytes, loadedAbciRes)
require.NoError(t, err) require.NoError(t, err)
mock := newMockProxyApp(ctx, logger, []byte("mock_hash"), loadedAbciRes)
mock, err := newMockProxyApp(ctx, logger, []byte("mock_hash"), loadedAbciRes)
require.NoError(t, err)
abciRes := new(tmstate.ABCIResponses) abciRes := new(tmstate.ABCIResponses)
abciRes.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs)) abciRes.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs))
@ -701,18 +713,17 @@ func TestMockProxyApp(t *testing.T) {
assert.True(t, invalidTxs == 0) assert.True(t, invalidTxs == 0)
} }
func tempWALWithData(data []byte) string {
func tempWALWithData(t *testing.T, data []byte) string {
t.Helper()
walFile, err := os.CreateTemp("", "wal") walFile, err := os.CreateTemp("", "wal")
if err != nil {
panic(fmt.Errorf("failed to create temp WAL file: %w", err))
}
require.NoError(t, err, "failed to create temp WAL file")
_, err = walFile.Write(data) _, err = walFile.Write(data)
if err != nil {
panic(fmt.Errorf("failed to write to temp WAL file: %w", err))
}
if err := walFile.Close(); err != nil {
panic(fmt.Errorf("failed to close temp WAL file: %w", err))
}
require.NoError(t, err, "failed to write to temp WAL file")
require.NoError(t, walFile.Close(), "failed to close temp WAL file")
return walFile.Name() return walFile.Name()
} }
@ -755,7 +766,7 @@ func testHandshakeReplay(
defer func() { _ = os.RemoveAll(testConfig.RootDir) }() defer func() { _ = os.RemoveAll(testConfig.RootDir) }()
walBody, err := WALWithNBlocks(ctx, t, numBlocks) walBody, err := WALWithNBlocks(ctx, t, numBlocks)
require.NoError(t, err) require.NoError(t, err)
walFile := tempWALWithData(walBody)
walFile := tempWALWithData(t, walBody)
cfg.Consensus.SetWalFile(walFile) cfg.Consensus.SetWalFile(walFile)
privVal, err := privval.LoadFilePV(cfg.PrivValidator.KeyFile(), cfg.PrivValidator.StateFile()) privVal, err := privval.LoadFilePV(cfg.PrivValidator.KeyFile(), cfg.PrivValidator.StateFile())
@ -766,8 +777,7 @@ func testHandshakeReplay(
err = wal.Start(ctx) err = wal.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(func() { cancel(); wal.Wait() }) t.Cleanup(func() { cancel(); wal.Wait() })
chain, commits, err = makeBlockchainFromWAL(wal)
require.NoError(t, err)
chain, commits = makeBlockchainFromWAL(t, wal)
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
require.NoError(t, err) require.NoError(t, err)
stateDB, genesisState, store = stateAndStore(t, cfg, pubKey, kvstore.ProtocolVersion) stateDB, genesisState, store = stateAndStore(t, cfg, pubKey, kvstore.ProtocolVersion)
@ -897,21 +907,19 @@ func buildAppStateFromChain(
mode uint, mode uint,
blockStore *mockBlockStore, blockStore *mockBlockStore,
) { ) {
t.Helper()
// start a new app without handshake, play nBlocks blocks // start a new app without handshake, play nBlocks blocks
if err := proxyApp.Start(ctx); err != nil {
panic(err)
}
require.NoError(t, proxyApp.Start(ctx))
state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version
validators := types.TM2PB.ValidatorUpdates(state.Validators) validators := types.TM2PB.ValidatorUpdates(state.Validators)
if _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
_, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
Validators: validators, Validators: validators,
}); err != nil {
panic(err)
}
if err := stateStore.Save(state); err != nil { // save height 1's validatorsInfo
panic(err)
}
})
require.NoError(t, err)
require.NoError(t, stateStore.Save(state)) // save height 1's validatorsInfo
switch mode { switch mode {
case 0: case 0:
for i := 0; i < nBlocks; i++ { for i := 0; i < nBlocks; i++ {
@ -930,7 +938,7 @@ func buildAppStateFromChain(
state = applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp, blockStore) state = applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[nBlocks-1], proxyApp, blockStore)
} }
default: default:
panic(fmt.Sprintf("unknown mode %v", mode))
require.Fail(t, "unknown mode %v", mode)
} }
} }
@ -949,6 +957,8 @@ func buildTMStateFromChain(
mode uint, mode uint,
blockStore *mockBlockStore, blockStore *mockBlockStore,
) sm.State { ) sm.State {
t.Helper()
// run the whole chain against this client to build up the tendermint state // run the whole chain against this client to build up the tendermint state
kvstoreApp := kvstore.NewPersistentKVStoreApplication( kvstoreApp := kvstore.NewPersistentKVStoreApplication(
filepath.Join(cfg.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode))) filepath.Join(cfg.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))
@ -956,20 +966,17 @@ func buildTMStateFromChain(
clientCreator := abciclient.NewLocalCreator(kvstoreApp) clientCreator := abciclient.NewLocalCreator(kvstoreApp)
proxyApp := proxy.NewAppConns(clientCreator, logger, proxy.NopMetrics()) proxyApp := proxy.NewAppConns(clientCreator, logger, proxy.NopMetrics())
if err := proxyApp.Start(ctx); err != nil {
panic(err)
}
require.NoError(t, proxyApp.Start(ctx))
state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version
validators := types.TM2PB.ValidatorUpdates(state.Validators) validators := types.TM2PB.ValidatorUpdates(state.Validators)
if _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
_, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
Validators: validators, Validators: validators,
}); err != nil {
panic(err)
}
if err := stateStore.Save(state); err != nil { // save height 1's validatorsInfo
panic(err)
}
})
require.NoError(t, err)
require.NoError(t, stateStore.Save(state))
switch mode { switch mode {
case 0: case 0:
// sync right up // sync right up
@ -988,7 +995,7 @@ func buildTMStateFromChain(
// get the right next appHash but keep the state back // get the right next appHash but keep the state back
applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, blockStore) applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, blockStore)
default: default:
panic(fmt.Sprintf("unknown mode %v", mode))
require.Fail(t, "unknown mode %v", mode)
} }
return state return state
@ -1089,17 +1096,14 @@ func (app *badApp) Commit() abci.ResponseCommit {
//-------------------------- //--------------------------
// utils for making blocks // utils for making blocks
func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
func makeBlockchainFromWAL(t *testing.T, wal WAL) ([]*types.Block, []*types.Commit) {
t.Helper()
var height int64 var height int64
// Search for height marker // Search for height marker
gr, found, err := wal.SearchForEndHeight(height, &WALSearchOptions{}) gr, found, err := wal.SearchForEndHeight(height, &WALSearchOptions{})
if err != nil {
return nil, nil, err
}
if !found {
return nil, nil, fmt.Errorf("wal does not contain height %d", height)
}
require.NoError(t, err)
require.True(t, found, "wal does not contain height %d", height)
defer gr.Close() defer gr.Close()
// log.Notice("Build a blockchain by reading from the WAL") // log.Notice("Build a blockchain by reading from the WAL")
@ -1116,9 +1120,8 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
msg, err := dec.Decode() msg, err := dec.Decode()
if err == io.EOF { if err == io.EOF {
break break
} else if err != nil {
return nil, nil, err
} }
require.NoError(t, err)
piece := readPieceFromWAL(msg) piece := readPieceFromWAL(msg)
if piece == nil { if piece == nil {
@ -1131,25 +1134,20 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
if thisBlockParts != nil { if thisBlockParts != nil {
var pbb = new(tmproto.Block) var pbb = new(tmproto.Block)
bz, err := io.ReadAll(thisBlockParts.GetReader()) bz, err := io.ReadAll(thisBlockParts.GetReader())
if err != nil {
panic(err)
}
err = proto.Unmarshal(bz, pbb)
if err != nil {
panic(err)
}
require.NoError(t, err)
require.NoError(t, proto.Unmarshal(bz, pbb))
block, err := types.BlockFromProto(pbb) block, err := types.BlockFromProto(pbb)
if err != nil {
panic(err)
}
require.NoError(t, err)
require.Equal(t, block.Height, height+1,
"read bad block from wal. got height %d, expected %d", block.Height, height+1)
if block.Height != height+1 {
panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1))
}
commitHeight := thisBlockCommit.Height commitHeight := thisBlockCommit.Height
if commitHeight != height+1 {
panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
}
require.Equal(t, commitHeight, height+1,
"commit doesnt match. got height %d, expected %d", commitHeight, height+1)
blocks = append(blocks, block) blocks = append(blocks, block)
commits = append(commits, thisBlockCommit) commits = append(commits, thisBlockCommit)
height++ height++
@ -1158,9 +1156,7 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
thisBlockParts = types.NewPartSetFromHeader(*p) thisBlockParts = types.NewPartSetFromHeader(*p)
case *types.Part: case *types.Part:
_, err := thisBlockParts.AddPart(p) _, err := thisBlockParts.AddPart(p)
if err != nil {
return nil, nil, err
}
require.NoError(t, err)
case *types.Vote: case *types.Vote:
if p.Type == tmproto.PrecommitType { if p.Type == tmproto.PrecommitType {
thisBlockCommit = types.NewCommit(p.Height, p.Round, thisBlockCommit = types.NewCommit(p.Height, p.Round,
@ -1170,28 +1166,21 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
} }
// grab the last block too // grab the last block too
bz, err := io.ReadAll(thisBlockParts.GetReader()) bz, err := io.ReadAll(thisBlockParts.GetReader())
if err != nil {
panic(err)
}
require.NoError(t, err)
var pbb = new(tmproto.Block) var pbb = new(tmproto.Block)
err = proto.Unmarshal(bz, pbb)
if err != nil {
panic(err)
}
require.NoError(t, proto.Unmarshal(bz, pbb))
block, err := types.BlockFromProto(pbb) block, err := types.BlockFromProto(pbb)
if err != nil {
panic(err)
}
if block.Height != height+1 {
panic(fmt.Sprintf("read bad block from wal. got height %d, expected %d", block.Height, height+1))
}
require.NoError(t, err)
require.Equal(t, block.Height, height+1, "read bad block from wal. got height %d, expected %d", block.Height, height+1)
commitHeight := thisBlockCommit.Height commitHeight := thisBlockCommit.Height
if commitHeight != height+1 {
panic(fmt.Sprintf("commit doesnt match. got height %d, expected %d", commitHeight, height+1))
}
require.Equal(t, commitHeight, height+1, "commit does not match. got height %d, expected %d", commitHeight, height+1)
blocks = append(blocks, block) blocks = append(blocks, block)
commits = append(commits, thisBlockCommit) commits = append(commits, thisBlockCommit)
return blocks, commits, nil
return blocks, commits
} }
func readPieceFromWAL(msg *TimedWALMessage) interface{} { func readPieceFromWAL(msg *TimedWALMessage) interface{} {


+ 304
- 335
internal/consensus/state_test.go
File diff suppressed because it is too large
View File


+ 5
- 4
internal/consensus/types/height_vote_set_test.go View File

@ -2,6 +2,7 @@ package types
import ( import (
"context" "context"
"log"
"os" "os"
"testing" "testing"
@ -21,7 +22,7 @@ func TestMain(m *testing.M) {
var err error var err error
cfg, err = config.ResetTestRoot("consensus_height_vote_set_test") cfg, err = config.ResetTestRoot("consensus_height_vote_set_test")
if err != nil { if err != nil {
panic(err)
log.Fatal(err)
} }
code := m.Run() code := m.Run()
os.RemoveAll(cfg.RootDir) os.RemoveAll(cfg.RootDir)
@ -71,11 +72,11 @@ func makeVoteHR(
valIndex, round int32, valIndex, round int32,
privVals []types.PrivValidator, privVals []types.PrivValidator,
) *types.Vote { ) *types.Vote {
t.Helper()
privVal := privVals[valIndex] privVal := privVals[valIndex]
pubKey, err := privVal.GetPubKey(ctx) pubKey, err := privVal.GetPubKey(ctx)
if err != nil {
panic(err)
}
require.NoError(t, err)
randBytes := tmrand.Bytes(tmhash.Size) randBytes := tmrand.Bytes(tmhash.Size)


+ 1
- 1
internal/consensus/wal_test.go View File

@ -140,7 +140,7 @@ func TestWALSearchForEndHeight(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
walFile := tempWALWithData(walBody)
walFile := tempWALWithData(t, walBody)
wal, err := NewWAL(log.TestingLogger(), walFile) wal, err := NewWAL(log.TestingLogger(), walFile)
require.NoError(t, err) require.NoError(t, err)


+ 1
- 3
internal/evidence/verify_test.go View File

@ -592,9 +592,7 @@ func makeVote(
vpb := v.ToProto() vpb := v.ToProto()
err = val.SignVote(ctx, chainID, vpb) err = val.SignVote(ctx, chainID, vpb)
if err != nil {
panic(err)
}
require.NoError(t, err)
v.Signature = vpb.Signature v.Signature = vpb.Signature
return v return v
} }


+ 6
- 7
internal/libs/protoio/io_test.go View File

@ -44,7 +44,8 @@ import (
"github.com/tendermint/tendermint/internal/libs/protoio" "github.com/tendermint/tendermint/internal/libs/protoio"
) )
func iotest(writer protoio.WriteCloser, reader protoio.ReadCloser) error {
func iotest(t *testing.T, writer protoio.WriteCloser, reader protoio.ReadCloser) error {
t.Helper()
varint := make([]byte, binary.MaxVarintLen64) varint := make([]byte, binary.MaxVarintLen64)
size := 1000 size := 1000
msgs := make([]*test.NinOptNative, size) msgs := make([]*test.NinOptNative, size)
@ -94,9 +95,7 @@ func iotest(writer protoio.WriteCloser, reader protoio.ReadCloser) error {
} }
i++ i++
} }
if i != size {
panic("not enough messages read")
}
require.NotEqual(t, size, i)
if err := reader.Close(); err != nil { if err := reader.Close(); err != nil {
return err return err
} }
@ -121,7 +120,7 @@ func TestVarintNormal(t *testing.T) {
buf := newBuffer() buf := newBuffer()
writer := protoio.NewDelimitedWriter(buf) writer := protoio.NewDelimitedWriter(buf)
reader := protoio.NewDelimitedReader(buf, 1024*1024) reader := protoio.NewDelimitedReader(buf, 1024*1024)
err := iotest(writer, reader)
err := iotest(t, writer, reader)
require.NoError(t, err) require.NoError(t, err)
require.True(t, buf.closed, "did not close buffer") require.True(t, buf.closed, "did not close buffer")
} }
@ -130,7 +129,7 @@ func TestVarintNoClose(t *testing.T) {
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
writer := protoio.NewDelimitedWriter(buf) writer := protoio.NewDelimitedWriter(buf)
reader := protoio.NewDelimitedReader(buf, 1024*1024) reader := protoio.NewDelimitedReader(buf, 1024*1024)
err := iotest(writer, reader)
err := iotest(t, writer, reader)
require.NoError(t, err) require.NoError(t, err)
} }
@ -139,7 +138,7 @@ func TestVarintMaxSize(t *testing.T) {
buf := newBuffer() buf := newBuffer()
writer := protoio.NewDelimitedWriter(buf) writer := protoio.NewDelimitedWriter(buf)
reader := protoio.NewDelimitedReader(buf, 20) reader := protoio.NewDelimitedReader(buf, 20)
err := iotest(writer, reader)
err := iotest(t, writer, reader)
require.Error(t, err) require.Error(t, err)
} }


+ 5
- 6
internal/libs/protoio/writer_test.go View File

@ -14,11 +14,10 @@ import (
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
) )
func aVote() *types.Vote {
func aVote(t testing.TB) *types.Vote {
t.Helper()
var stamp, err = time.Parse(types.TimeFormat, "2017-12-25T03:00:01.234Z") var stamp, err = time.Parse(types.TimeFormat, "2017-12-25T03:00:01.234Z")
if err != nil {
panic(err)
}
require.NoError(t, err)
return &types.Vote{ return &types.Vote{
Type: tmproto.SignedMsgType(byte(tmproto.PrevoteType)), Type: tmproto.SignedMsgType(byte(tmproto.PrevoteType)),
@ -58,14 +57,14 @@ var sink interface{}
func BenchmarkMarshalDelimitedWithMarshalTo(b *testing.B) { func BenchmarkMarshalDelimitedWithMarshalTo(b *testing.B) {
msgs := []proto.Message{ msgs := []proto.Message{
aVote().ToProto(),
aVote(b).ToProto(),
} }
benchmarkMarshalDelimited(b, msgs) benchmarkMarshalDelimited(b, msgs)
} }
func BenchmarkMarshalDelimitedNoMarshalTo(b *testing.B) { func BenchmarkMarshalDelimitedNoMarshalTo(b *testing.B) {
msgs := []proto.Message{ msgs := []proto.Message{
&excludedMarshalTo{aVote().ToProto()},
&excludedMarshalTo{aVote(b).ToProto()},
} }
benchmarkMarshalDelimited(b, msgs) benchmarkMarshalDelimited(b, msgs)
} }


+ 5
- 5
internal/state/execution_test.go View File

@ -47,7 +47,7 @@ func TestApplyBlock(t *testing.T) {
err := proxyApp.Start(ctx) err := proxyApp.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
state, stateDB, _ := makeState(1, 1)
state, stateDB, _ := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp.Consensus(), blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp.Consensus(),
@ -78,7 +78,7 @@ func TestBeginBlockValidators(t *testing.T) {
err := proxyApp.Start(ctx) err := proxyApp.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
state, stateDB, _ := makeState(2, 2)
state, stateDB, _ := makeState(t, 2, 2)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
prevHash := state.LastBlockID.Hash prevHash := state.LastBlockID.Hash
@ -144,7 +144,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
err := proxyApp.Start(ctx) err := proxyApp.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
state, stateDB, privVals := makeState(1, 1)
state, stateDB, privVals := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
defaultEvidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC) defaultEvidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
@ -377,7 +377,7 @@ func TestEndBlockValidatorUpdates(t *testing.T) {
err := proxyApp.Start(ctx) err := proxyApp.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
state, stateDB, _ := makeState(1, 1)
state, stateDB, _ := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
@ -452,7 +452,7 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
err := proxyApp.Start(ctx) err := proxyApp.Start(ctx)
require.NoError(t, err) require.NoError(t, err)
state, stateDB, _ := makeState(1, 1)
state, stateDB, _ := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
blockExec := sm.NewBlockExecutor( blockExec := sm.NewBlockExecutor(


+ 8
- 10
internal/state/helpers_test.go View File

@ -107,7 +107,7 @@ func makeValidCommit(
return types.NewCommit(height, 0, blockID, sigs), nil return types.NewCommit(height, 0, blockID, sigs), nil
} }
func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
vals := make([]types.GenesisValidator, nVals) vals := make([]types.GenesisValidator, nVals)
privVals := make(map[string]types.PrivValidator, nVals) privVals := make(map[string]types.PrivValidator, nVals)
for i := 0; i < nVals; i++ { for i := 0; i < nVals; i++ {
@ -130,16 +130,13 @@ func makeState(nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValida
stateDB := dbm.NewMemDB() stateDB := dbm.NewMemDB()
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
if err := stateStore.Save(s); err != nil {
panic(err)
}
require.NoError(t, stateStore.Save(s))
for i := 1; i < height; i++ { for i := 1; i < height; i++ {
s.LastBlockHeight++ s.LastBlockHeight++
s.LastValidators = s.Validators.Copy() s.LastValidators = s.Validators.Copy()
if err := stateStore.Save(s); err != nil {
panic(err)
}
require.NoError(t, stateStore.Save(s))
} }
return s, stateDB, privVals return s, stateDB, privVals
@ -189,6 +186,7 @@ func makeHeaderPartsResponsesValPowerChange(
state sm.State, state sm.State,
power int64, power int64,
) (types.Header, types.BlockID, *tmstate.ABCIResponses) { ) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
t.Helper()
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit)) block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err) require.NoError(t, err)
@ -202,9 +200,8 @@ func makeHeaderPartsResponsesValPowerChange(
_, val := state.NextValidators.GetByIndex(0) _, val := state.NextValidators.GetByIndex(0)
if val.VotingPower != power { if val.VotingPower != power {
vPbPk, err := encoding.PubKeyToProto(val.PubKey) vPbPk, err := encoding.PubKeyToProto(val.PubKey)
if err != nil {
panic(err)
}
require.NoError(t, err)
abciResponses.EndBlock = &abci.ResponseEndBlock{ abciResponses.EndBlock = &abci.ResponseEndBlock{
ValidatorUpdates: []abci.ValidatorUpdate{ ValidatorUpdates: []abci.ValidatorUpdate{
{PubKey: vPbPk, Power: power}, {PubKey: vPbPk, Power: power},
@ -220,6 +217,7 @@ func makeHeaderPartsResponsesParams(
state sm.State, state sm.State,
params *types.ConsensusParams, params *types.ConsensusParams,
) (types.Header, types.BlockID, *tmstate.ABCIResponses) { ) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
t.Helper()
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit)) block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
require.NoError(t, err) require.NoError(t, err)


+ 3
- 3
internal/state/validation_test.go View File

@ -34,7 +34,7 @@ func TestValidateBlockHeader(t *testing.T) {
proxyApp := newTestApp() proxyApp := newTestApp()
require.NoError(t, proxyApp.Start(ctx)) require.NoError(t, proxyApp.Start(ctx))
state, stateDB, privVals := makeState(3, 1)
state, stateDB, privVals := makeState(t, 3, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
blockExec := sm.NewBlockExecutor( blockExec := sm.NewBlockExecutor(
@ -125,7 +125,7 @@ func TestValidateBlockCommit(t *testing.T) {
proxyApp := newTestApp() proxyApp := newTestApp()
require.NoError(t, proxyApp.Start(ctx)) require.NoError(t, proxyApp.Start(ctx))
state, stateDB, privVals := makeState(1, 1)
state, stateDB, privVals := makeState(t, 1, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
blockExec := sm.NewBlockExecutor( blockExec := sm.NewBlockExecutor(
@ -253,7 +253,7 @@ func TestValidateBlockEvidence(t *testing.T) {
proxyApp := newTestApp() proxyApp := newTestApp()
require.NoError(t, proxyApp.Start(ctx)) require.NoError(t, proxyApp.Start(ctx))
state, stateDB, privVals := makeState(4, 1)
state, stateDB, privVals := makeState(t, 4, 1)
stateStore := sm.NewStore(stateDB) stateStore := sm.NewStore(stateDB)
blockStore := store.NewBlockStore(dbm.NewMemDB()) blockStore := store.NewBlockStore(dbm.NewMemDB())
defaultEvidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC) defaultEvidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)


+ 14
- 7
internal/store/store_test.go View File

@ -46,18 +46,18 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit {
commitSigs) commitSigs)
} }
func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore, cleanupFunc) {
func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore, cleanupFunc, error) {
cfg, err := config.ResetTestRoot("blockchain_reactor_test") cfg, err := config.ResetTestRoot("blockchain_reactor_test")
if err != nil { if err != nil {
panic(err)
return sm.State{}, nil, nil, err
} }
blockDB := dbm.NewMemDB() blockDB := dbm.NewMemDB()
state, err := sm.MakeGenesisStateFromFile(cfg.GenesisFile()) state, err := sm.MakeGenesisStateFromFile(cfg.GenesisFile())
if err != nil { if err != nil {
panic(fmt.Errorf("error constructing state from genesis file: %w", err))
return sm.State{}, nil, nil, fmt.Errorf("error constructing state from genesis file: %w", err)
} }
return state, NewBlockStore(blockDB), func() { os.RemoveAll(cfg.RootDir) }
return state, NewBlockStore(blockDB), func() { os.RemoveAll(cfg.RootDir) }, nil
} }
func freshBlockStore() (*BlockStore, dbm.DB) { func freshBlockStore() (*BlockStore, dbm.DB) {
@ -77,7 +77,12 @@ var (
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
var cleanup cleanupFunc var cleanup cleanupFunc
var err error var err error
state, _, cleanup = makeStateAndBlockStore(log.NewNopLogger())
state, _, cleanup, err = makeStateAndBlockStore(log.NewNopLogger())
if err != nil {
stdlog.Fatal(err)
}
block, err = factory.MakeBlock(state, 1, new(types.Commit)) block, err = factory.MakeBlock(state, 1, new(types.Commit))
if err != nil { if err != nil {
@ -97,8 +102,9 @@ func TestMain(m *testing.M) {
// TODO: This test should be simplified ... // TODO: This test should be simplified ...
func TestBlockStoreSaveLoadBlock(t *testing.T) { func TestBlockStoreSaveLoadBlock(t *testing.T) {
state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger())
state, bs, cleanup, err := makeStateAndBlockStore(log.NewNopLogger())
defer cleanup() defer cleanup()
require.NoError(t, err)
require.Equal(t, bs.Base(), int64(0), "initially the base should be zero") require.Equal(t, bs.Base(), int64(0), "initially the base should be zero")
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
@ -488,8 +494,9 @@ func TestLoadBlockMeta(t *testing.T) {
} }
func TestBlockFetchAtHeight(t *testing.T) { func TestBlockFetchAtHeight(t *testing.T) {
state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger())
state, bs, cleanup, err := makeStateAndBlockStore(log.NewNopLogger())
defer cleanup() defer cleanup()
require.NoError(t, err)
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero") require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
block, err := factory.MakeBlock(state, bs.Height()+1, new(types.Commit)) block, err := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
require.NoError(t, err) require.NoError(t, err)


+ 2
- 4
libs/bits/bit_array_test.go View File

@ -3,7 +3,6 @@ package bits
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt"
"math" "math"
"testing" "testing"
@ -149,9 +148,8 @@ func TestBytes(t *testing.T) {
bA := NewBitArray(4) bA := NewBitArray(4)
bA.SetIndex(0, true) bA.SetIndex(0, true)
check := func(bA *BitArray, bz []byte) { check := func(bA *BitArray, bz []byte) {
if !bytes.Equal(bA.Bytes(), bz) {
panic(fmt.Sprintf("Expected %X but got %X", bz, bA.Bytes()))
}
require.True(t, bytes.Equal(bA.Bytes(), bz),
"Expected %X but got %X", bz, bA.Bytes())
} }
check(bA, []byte{0x01}) check(bA, []byte{0x01})
bA.SetIndex(3, true) bA.SetIndex(3, true)


+ 6
- 7
libs/cli/setup_test.go View File

@ -54,11 +54,10 @@ func TestSetupEnv(t *testing.T) {
} }
} }
func tempDir() string {
func tempDir(t *testing.T) string {
t.Helper()
cdir, err := os.MkdirTemp("", "test-cli") cdir, err := os.MkdirTemp("", "test-cli")
if err != nil {
panic(err)
}
require.NoError(t, err)
return cdir return cdir
} }
@ -66,7 +65,7 @@ func TestSetupConfig(t *testing.T) {
// we pre-create two config files we can refer to in the rest of // we pre-create two config files we can refer to in the rest of
// the test cases. // the test cases.
cval1 := "fubble" cval1 := "fubble"
conf1 := tempDir()
conf1 := tempDir(t)
err := WriteConfigVals(conf1, map[string]string{"boo": cval1}) err := WriteConfigVals(conf1, map[string]string{"boo": cval1})
require.NoError(t, err) require.NoError(t, err)
@ -125,11 +124,11 @@ func TestSetupUnmarshal(t *testing.T) {
// we pre-create two config files we can refer to in the rest of // we pre-create two config files we can refer to in the rest of
// the test cases. // the test cases.
cval1, cval2 := "someone", "else" cval1, cval2 := "someone", "else"
conf1 := tempDir()
conf1 := tempDir(t)
err := WriteConfigVals(conf1, map[string]string{"name": cval1}) err := WriteConfigVals(conf1, map[string]string{"name": cval1})
require.NoError(t, err) require.NoError(t, err)
// even with some ignored fields, should be no problem // even with some ignored fields, should be no problem
conf2 := tempDir()
conf2 := tempDir(t)
err = WriteConfigVals(conf2, map[string]string{"name": cval2, "foo": "bar"}) err = WriteConfigVals(conf2, map[string]string{"name": cval2, "foo": "bar"})
require.NoError(t, err) require.NoError(t, err)


+ 3
- 3
node/node_test.go View File

@ -10,6 +10,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/fortytw2/leaktest"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
dbm "github.com/tendermint/tm-db" dbm "github.com/tendermint/tm-db"
@ -151,6 +152,7 @@ func TestNodeSetAppVersion(t *testing.T) {
func TestNodeSetPrivValTCP(t *testing.T) { func TestNodeSetPrivValTCP(t *testing.T) {
addr := "tcp://" + testFreeAddr(t) addr := "tcp://" + testFreeAddr(t)
t.Cleanup(leaktest.Check(t))
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
@ -173,9 +175,7 @@ func TestNodeSetPrivValTCP(t *testing.T) {
go func() { go func() {
err := signerServer.Start(ctx) err := signerServer.Start(ctx)
if err != nil {
panic(err)
}
require.NoError(t, err)
}() }()
defer signerServer.Stop() //nolint:errcheck // ignore for tests defer signerServer.Stop() //nolint:errcheck // ignore for tests


+ 2
- 2
rpc/client/event_test.go View File

@ -2,7 +2,6 @@ package client_test
import ( import (
"context" "context"
"fmt"
"testing" "testing"
"time" "time"
@ -26,6 +25,7 @@ func MakeTxKV() ([]byte, []byte, []byte) {
} }
func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string, c client.Client) { func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string, c client.Client) {
t.Helper()
// make the tx // make the tx
_, _, tx := MakeTxKV() _, _, tx := MakeTxKV()
@ -43,7 +43,7 @@ func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string,
case "sync": case "sync":
txres, err = c.BroadcastTxSync(ctx, tx) txres, err = c.BroadcastTxSync(ctx, tx)
default: default:
panic(fmt.Sprintf("Unknown broadcastMethod %s", broadcastMethod))
require.FailNowf(t, "Unknown broadcastMethod %s", broadcastMethod)
} }
if assert.NoError(t, err) { if assert.NoError(t, err) {
assert.Equal(t, txres.Code, abci.CodeTypeOK) assert.Equal(t, txres.Code, abci.CodeTypeOK)


+ 17
- 18
rpc/jsonrpc/client/ws_client_test.go View File

@ -20,9 +20,10 @@ import (
var wsCallTimeout = 5 * time.Second var wsCallTimeout = 5 * time.Second
type myHandler struct {
type myTestHandler struct {
closeConnAfterRead bool closeConnAfterRead bool
mtx sync.RWMutex mtx sync.RWMutex
t *testing.T
} }
var upgrader = websocket.Upgrader{ var upgrader = websocket.Upgrader{
@ -30,11 +31,10 @@ var upgrader = websocket.Upgrader{
WriteBufferSize: 1024, WriteBufferSize: 1024,
} }
func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
func (h *myTestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil) conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
panic(err)
}
require.NoError(h.t, err)
defer conn.Close() defer conn.Close()
for { for {
messageType, in, err := conn.ReadMessage() messageType, in, err := conn.ReadMessage()
@ -44,17 +44,16 @@ func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
var req rpctypes.RPCRequest var req rpctypes.RPCRequest
err = json.Unmarshal(in, &req) err = json.Unmarshal(in, &req)
if err != nil {
panic(err)
}
require.NoError(h.t, err)
func() {
h.mtx.RLock()
defer h.mtx.RUnlock()
h.mtx.RLock()
if h.closeConnAfterRead {
if err := conn.Close(); err != nil {
panic(err)
if h.closeConnAfterRead {
require.NoError(h.t, conn.Close())
} }
}
h.mtx.RUnlock()
}()
res := json.RawMessage(`{}`) res := json.RawMessage(`{}`)
emptyRespBytes, _ := json.Marshal(rpctypes.RPCResponse{Result: res, ID: req.ID}) emptyRespBytes, _ := json.Marshal(rpctypes.RPCResponse{Result: res, ID: req.ID})
@ -68,7 +67,7 @@ func TestWSClientReconnectsAfterReadFailure(t *testing.T) {
t.Cleanup(leaktest.Check(t)) t.Cleanup(leaktest.Check(t))
// start server // start server
h := &myHandler{}
h := &myTestHandler{t: t}
s := httptest.NewServer(h) s := httptest.NewServer(h)
defer s.Close() defer s.Close()
@ -100,7 +99,7 @@ func TestWSClientReconnectsAfterWriteFailure(t *testing.T) {
t.Cleanup(leaktest.Check(t)) t.Cleanup(leaktest.Check(t))
// start server // start server
h := &myHandler{}
h := &myTestHandler{t: t}
s := httptest.NewServer(h) s := httptest.NewServer(h)
defer s.Close() defer s.Close()
@ -130,7 +129,7 @@ func TestWSClientReconnectFailure(t *testing.T) {
t.Cleanup(leaktest.Check(t)) t.Cleanup(leaktest.Check(t))
// start server // start server
h := &myHandler{}
h := &myTestHandler{t: t}
s := httptest.NewServer(h) s := httptest.NewServer(h)
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -185,7 +184,7 @@ func TestNotBlockingOnStop(t *testing.T) {
t.Cleanup(leaktest.Check(t)) t.Cleanup(leaktest.Check(t))
timeout := 3 * time.Second timeout := 3 * time.Second
s := httptest.NewServer(&myHandler{})
s := httptest.NewServer(&myTestHandler{t: t})
defer s.Close() defer s.Close()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()


+ 10
- 6
rpc/jsonrpc/jsonrpc_test.go View File

@ -6,6 +6,7 @@ import (
crand "crypto/rand" crand "crypto/rand"
"encoding/json" "encoding/json"
"fmt" "fmt"
stdlog "log"
mrand "math/rand" mrand "math/rand"
"net/http" "net/http"
"os" "os"
@ -84,22 +85,24 @@ func TestMain(m *testing.M) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
setup(ctx)
if err := setup(ctx); err != nil {
stdlog.Fatal(err.Error())
}
code := m.Run() code := m.Run()
os.Exit(code) os.Exit(code)
} }
// launch unix and tcp servers // launch unix and tcp servers
func setup(ctx context.Context) {
func setup(ctx context.Context) error {
logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false) logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
cmd := exec.Command("rm", "-f", unixSocket) cmd := exec.Command("rm", "-f", unixSocket)
err := cmd.Start() err := cmd.Start()
if err != nil { if err != nil {
panic(err)
return err
} }
if err = cmd.Wait(); err != nil { if err = cmd.Wait(); err != nil {
panic(err)
return err
} }
tcpLogger := logger.With("socket", "tcp") tcpLogger := logger.With("socket", "tcp")
@ -111,7 +114,7 @@ func setup(ctx context.Context) {
config := server.DefaultConfig() config := server.DefaultConfig()
listener1, err := server.Listen(tcpAddr, config.MaxOpenConnections) listener1, err := server.Listen(tcpAddr, config.MaxOpenConnections)
if err != nil { if err != nil {
panic(err)
return err
} }
go func() { go func() {
if err := server.Serve(ctx, listener1, mux, tcpLogger, config); err != nil { if err := server.Serve(ctx, listener1, mux, tcpLogger, config); err != nil {
@ -127,7 +130,7 @@ func setup(ctx context.Context) {
mux2.HandleFunc(websocketEndpoint, wm.WebsocketHandler) mux2.HandleFunc(websocketEndpoint, wm.WebsocketHandler)
listener2, err := server.Listen(unixAddr, config.MaxOpenConnections) listener2, err := server.Listen(unixAddr, config.MaxOpenConnections)
if err != nil { if err != nil {
panic(err)
return err
} }
go func() { go func() {
if err := server.Serve(ctx, listener2, mux2, unixLogger, config); err != nil { if err := server.Serve(ctx, listener2, mux2, unixLogger, config); err != nil {
@ -137,6 +140,7 @@ func setup(ctx context.Context) {
// wait for servers to start // wait for servers to start
time.Sleep(time.Second * 2) time.Sleep(time.Second * 2)
return nil
} }
func echoViaHTTP(ctx context.Context, cl client.Caller, val string) (string, error) { func echoViaHTTP(ctx context.Context, cl client.Caller, val string) (string, error) {


+ 7
- 6
test/e2e/tests/validator_test.go View File

@ -37,7 +37,7 @@ func TestValidator_Sets(t *testing.T) {
} }
valSchedule := newValidatorSchedule(*node.Testnet) valSchedule := newValidatorSchedule(*node.Testnet)
valSchedule.Increment(first - node.Testnet.InitialHeight)
require.NoError(t, valSchedule.Increment(first-node.Testnet.InitialHeight))
for h := first; h <= last; h++ { for h := first; h <= last; h++ {
validators := []*types.Validator{} validators := []*types.Validator{}
@ -52,7 +52,7 @@ func TestValidator_Sets(t *testing.T) {
} }
require.Equal(t, valSchedule.Set.Validators, validators, require.Equal(t, valSchedule.Set.Validators, validators,
"incorrect validator set at height %v", h) "incorrect validator set at height %v", h)
valSchedule.Increment(1)
require.NoError(t, valSchedule.Increment(1))
} }
}) })
} }
@ -80,7 +80,7 @@ func TestValidator_Propose(t *testing.T) {
proposeCount++ proposeCount++
} }
} }
valSchedule.Increment(1)
require.NoError(t, valSchedule.Increment(1))
} }
require.False(t, proposeCount == 0 && expectCount > 0, require.False(t, proposeCount == 0 && expectCount > 0,
@ -123,7 +123,7 @@ func TestValidator_Sign(t *testing.T) {
} else { } else {
require.False(t, signed, "unexpected signature for block %v", block.LastCommit.Height) require.False(t, signed, "unexpected signature for block %v", block.LastCommit.Height)
} }
valSchedule.Increment(1)
require.NoError(t, valSchedule.Increment(1))
} }
require.False(t, signCount == 0 && expectCount > 0, require.False(t, signCount == 0 && expectCount > 0,
@ -154,7 +154,7 @@ func newValidatorSchedule(testnet e2e.Testnet) *validatorSchedule {
} }
} }
func (s *validatorSchedule) Increment(heights int64) {
func (s *validatorSchedule) Increment(heights int64) error {
for i := int64(0); i < heights; i++ { for i := int64(0); i < heights; i++ {
s.height++ s.height++
if s.height > 2 { if s.height > 2 {
@ -162,12 +162,13 @@ func (s *validatorSchedule) Increment(heights int64) {
// two blocks after they're returned. // two blocks after they're returned.
if update, ok := s.updates[s.height-2]; ok { if update, ok := s.updates[s.height-2]; ok {
if err := s.Set.UpdateWithChangeSet(makeVals(update)); err != nil { if err := s.Set.UpdateWithChangeSet(makeVals(update)); err != nil {
panic(err)
return err
} }
} }
} }
s.Set.IncrementProposerPriority(1) s.Set.IncrementProposerPriority(1)
} }
return nil
} }
func makeVals(valMap map[*e2e.Node]int64) []*types.Validator { func makeVals(valMap map[*e2e.Node]int64) []*types.Validator {


Loading…
Cancel
Save