mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-01 12:55:44 +00:00
tests: remove panics from test fixtures (#7522)
This commit is contained in:
@@ -18,17 +18,12 @@ import (
|
||||
)
|
||||
|
||||
// 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()
|
||||
config = cfg.DefaultConfig()
|
||||
}
|
||||
@@ -46,8 +41,9 @@ func testRootCmd() *cobra.Command {
|
||||
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()
|
||||
cmd := cli.PrepareBaseCmd(rootCmd, "TM", rootDir)
|
||||
@@ -73,7 +69,7 @@ func TestRootHome(t *testing.T) {
|
||||
for i, tc := range cases {
|
||||
idxString := strconv.Itoa(i)
|
||||
|
||||
err := testSetup(defaultRoot, tc.args, tc.env)
|
||||
err := testSetup(t, defaultRoot, tc.args, tc.env)
|
||||
require.NoError(t, err, idxString)
|
||||
|
||||
assert.Equal(t, tc.root, config.RootDir, idxString)
|
||||
@@ -105,7 +101,7 @@ func TestRootFlagsEnv(t *testing.T) {
|
||||
for i, tc := range cases {
|
||||
idxString := strconv.Itoa(i)
|
||||
|
||||
err := testSetup(defaultRoot, tc.args, tc.env)
|
||||
err := testSetup(t, defaultRoot, tc.args, tc.env)
|
||||
require.NoError(t, err, idxString)
|
||||
|
||||
assert.Equal(t, tc.logLevel, config.LogLevel, idxString)
|
||||
@@ -134,7 +130,7 @@ func TestRootConfig(t *testing.T) {
|
||||
for i, tc := range cases {
|
||||
defaultRoot := t.TempDir()
|
||||
idxString := strconv.Itoa(i)
|
||||
clearConfig(defaultRoot)
|
||||
clearConfig(t, defaultRoot)
|
||||
|
||||
// XXX: path must match cfg.defaultConfigPath
|
||||
configFilePath := filepath.Join(defaultRoot, "config")
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestKeyPath(t *testing.T) {
|
||||
case KeyEncodingHex:
|
||||
rand.Read(keys[i])
|
||||
default:
|
||||
panic("Unexpected encoding")
|
||||
require.Fail(t, "Unexpected encoding")
|
||||
}
|
||||
path = path.AppendKey(keys[i], enc)
|
||||
}
|
||||
|
||||
@@ -4,21 +4,61 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func toHex(bits []byte) string {
|
||||
return hex.EncodeToString(bits)
|
||||
}
|
||||
|
||||
func fromHex(bits string) []byte {
|
||||
func fromHex(bits string) ([]byte, error) {
|
||||
b, err := hex.DecodeString(bits)
|
||||
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) {
|
||||
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 {
|
||||
var key [32]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) {
|
||||
for i, v := range vectors {
|
||||
if len(v.plaintext) == 0 {
|
||||
|
||||
@@ -58,8 +58,8 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
|
||||
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)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
|
||||
|
||||
@@ -73,10 +73,9 @@ func configSetup(t *testing.T) *config.Config {
|
||||
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) {
|
||||
@@ -147,6 +146,7 @@ func (vs *validatorStub) signVote(
|
||||
// Sign vote for type/hash/header
|
||||
func signVote(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
vs *validatorStub,
|
||||
cfg *config.Config,
|
||||
voteType tmproto.SignedMsgType,
|
||||
@@ -155,9 +155,7 @@ func signVote(
|
||||
) *types.Vote {
|
||||
|
||||
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
|
||||
|
||||
@@ -166,14 +164,16 @@ func signVote(
|
||||
|
||||
func signVotes(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
cfg *config.Config,
|
||||
voteType tmproto.SignedMsgType,
|
||||
hash []byte,
|
||||
header types.PartSetHeader,
|
||||
vss ...*validatorStub) []*types.Vote {
|
||||
vss ...*validatorStub,
|
||||
) []*types.Vote {
|
||||
votes := make([]*types.Vote, len(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
|
||||
}
|
||||
@@ -196,16 +196,14 @@ func (vss ValidatorStubsByPower) Len() int {
|
||||
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 {
|
||||
vssi, err := vss[i].GetPubKey(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
vssj, err := vss[j].GetPubKey(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
if vss[i].VotingPower == vss[j].VotingPower {
|
||||
return bytes.Compare(vssi.Address(), vssj.Address()) == -1
|
||||
@@ -237,23 +235,22 @@ func decideProposal(
|
||||
height int64,
|
||||
round int32,
|
||||
) (proposal *types.Proposal, block *types.Block) {
|
||||
t.Helper()
|
||||
|
||||
cs1.mtx.Lock()
|
||||
block, blockParts, err := cs1.createProposalBlock()
|
||||
require.NoError(t, err)
|
||||
validRound := cs1.ValidRound
|
||||
chainID := cs1.state.ChainID
|
||||
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
|
||||
polRound, propBlockID := validRound, types.BlockID{Hash: block.Hash(), PartSetHeader: blockParts.Header()}
|
||||
proposal = types.NewProposal(height, round, polRound, propBlockID)
|
||||
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
|
||||
|
||||
@@ -268,6 +265,7 @@ func addVotes(to *State, votes ...*types.Vote) {
|
||||
|
||||
func signAddVotes(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
cfg *config.Config,
|
||||
to *State,
|
||||
voteType tmproto.SignedMsgType,
|
||||
@@ -275,7 +273,7 @@ func signAddVotes(
|
||||
header types.PartSetHeader,
|
||||
vss ...*validatorStub,
|
||||
) {
|
||||
addVotes(to, signVotes(ctx, cfg, voteType, hash, header, vss...)...)
|
||||
addVotes(to, signVotes(ctx, t, cfg, voteType, hash, header, vss...)...)
|
||||
}
|
||||
|
||||
func validatePrevote(
|
||||
@@ -286,37 +284,37 @@ func validatePrevote(
|
||||
privVal *validatorStub,
|
||||
blockHash []byte,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
prevotes := cs.Votes.Prevotes(round)
|
||||
pubKey, err := privVal.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
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 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 {
|
||||
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) {
|
||||
t.Helper()
|
||||
|
||||
votes := cs.LastCommit
|
||||
pv, err := privVal.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
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(
|
||||
@@ -329,42 +327,35 @@ func validatePrecommit(
|
||||
votedBlockHash,
|
||||
lockedBlockHash []byte,
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
precommits := cs.Votes.Precommits(thisRound)
|
||||
pv, err := privVal.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
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 vote.BlockID.Hash != nil {
|
||||
panic("Expected precommit to be for nil")
|
||||
}
|
||||
require.Nil(t, vote.BlockID.Hash, "Expected precommit to be for nil")
|
||||
} 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 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 {
|
||||
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(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
logger log.Logger,
|
||||
state sm.State,
|
||||
pv types.PrivValidator,
|
||||
app abci.Application,
|
||||
) (*State, error) {
|
||||
cfg, err := config.ResetTestRoot("consensus_state_test")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
) *State {
|
||||
t.Helper()
|
||||
|
||||
return newStateWithConfig(ctx, logger, cfg, state, pv, app), nil
|
||||
cfg, err := config.ResetTestRoot("consensus_state_test")
|
||||
require.NoError(t, err)
|
||||
|
||||
return newStateWithConfig(ctx, t, logger, cfg, state, pv, app)
|
||||
}
|
||||
|
||||
func newStateWithConfig(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
logger log.Logger,
|
||||
thisConfig *config.Config,
|
||||
state sm.State,
|
||||
pv types.PrivValidator,
|
||||
app abci.Application,
|
||||
) *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(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
logger log.Logger,
|
||||
thisConfig *config.Config,
|
||||
state sm.State,
|
||||
@@ -441,6 +436,8 @@ func newStateWithConfigAndBlockStore(
|
||||
app abci.Application,
|
||||
blockStore *store.BlockStore,
|
||||
) *State {
|
||||
t.Helper()
|
||||
|
||||
// one for mempool, one for consensus
|
||||
mtx := new(sync.Mutex)
|
||||
proxyAppConnMem := abciclient.NewLocalClient(logger, mtx, app)
|
||||
@@ -464,9 +461,7 @@ func newStateWithConfigAndBlockStore(
|
||||
// Make State
|
||||
stateDB := dbm.NewMemDB()
|
||||
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)
|
||||
cs := NewState(ctx,
|
||||
@@ -481,17 +476,16 @@ func newStateWithConfigAndBlockStore(
|
||||
cs.SetPrivValidator(ctx, pv)
|
||||
|
||||
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)
|
||||
return cs
|
||||
}
|
||||
|
||||
func loadPrivValidator(t *testing.T, cfg *config.Config) *privval.FilePV {
|
||||
t.Helper()
|
||||
privValidatorKeyFile := cfg.PrivValidator.KeyFile()
|
||||
ensureDir(filepath.Dir(privValidatorKeyFile), 0700)
|
||||
ensureDir(t, filepath.Dir(privValidatorKeyFile), 0700)
|
||||
privValidatorStateFile := cfg.PrivValidator.StateFile()
|
||||
privValidator, err := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
|
||||
require.NoError(t, err)
|
||||
@@ -505,16 +499,15 @@ func randState(
|
||||
cfg *config.Config,
|
||||
logger log.Logger,
|
||||
nValidators int,
|
||||
) (*State, []*validatorStub, error) {
|
||||
) (*State, []*validatorStub) {
|
||||
t.Helper()
|
||||
|
||||
// Get State
|
||||
state, privVals := randGenesisState(ctx, t, cfg, nValidators, false, 10)
|
||||
|
||||
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++ {
|
||||
vss[i] = newValidatorStub(privVals[i], int32(i))
|
||||
@@ -522,225 +515,208 @@ func randState(
|
||||
// since cs1 starts at 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 {
|
||||
case <-time.After(timeout):
|
||||
break
|
||||
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,
|
||||
ensureTimeout,
|
||||
"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(
|
||||
t,
|
||||
stepCh,
|
||||
ensureTimeout,
|
||||
"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,
|
||||
ensureTimeout,
|
||||
"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
|
||||
ensureNoNewEvent(
|
||||
ensureNoNewEvent(t,
|
||||
stepCh,
|
||||
timeoutDuration,
|
||||
"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 {
|
||||
case <-time.After(timeout):
|
||||
panic(errorMessage)
|
||||
t.Fatal(errorMessage)
|
||||
case msg := <-ch:
|
||||
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!
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewRound event")
|
||||
t.Fatal("Timeout expired while waiting for NewRound event")
|
||||
case msg := <-roundCh:
|
||||
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
|
||||
ensureNewEvent(timeoutCh, height, round, timeoutDuration,
|
||||
ensureNewEvent(t, timeoutCh, height, round, timeoutDuration,
|
||||
"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 {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewProposal event")
|
||||
t.Fatal("Timeout expired while waiting for NewProposal event")
|
||||
case msg := <-proposalCh:
|
||||
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")
|
||||
}
|
||||
|
||||
func ensureNewBlock(blockCh <-chan tmpubsub.Message, height int64) {
|
||||
func ensureNewBlock(t *testing.T, blockCh <-chan tmpubsub.Message, height int64) {
|
||||
t.Helper()
|
||||
|
||||
select {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewBlock event")
|
||||
t.Fatal("Timeout expired while waiting for NewBlock event")
|
||||
case msg := <-blockCh:
|
||||
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 {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewBlockHeader event")
|
||||
t.Fatal("Timeout expired while waiting for NewBlockHeader event")
|
||||
case msg := <-blockCh:
|
||||
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")
|
||||
}
|
||||
|
||||
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 {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewProposal event")
|
||||
t.Fatal("Timeout expired while waiting for NewProposal event")
|
||||
case msg := <-proposalCh:
|
||||
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 {
|
||||
case <-time.After(ensureTimeout):
|
||||
panic("Timeout expired while waiting for NewVote event")
|
||||
t.Fatal("Timeout expired while waiting for NewVote event")
|
||||
case msg := <-voteCh:
|
||||
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
|
||||
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 {
|
||||
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:
|
||||
}
|
||||
}
|
||||
|
||||
func ensureNewEventOnChannel(ch <-chan tmpubsub.Message) {
|
||||
func ensureNewEventOnChannel(t *testing.T, ch <-chan tmpubsub.Message) {
|
||||
t.Helper()
|
||||
select {
|
||||
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:
|
||||
}
|
||||
}
|
||||
@@ -761,7 +737,7 @@ func randConsensusState(
|
||||
nValidators int,
|
||||
testName string,
|
||||
tickerFunc func() TimeoutTicker,
|
||||
appFunc func() abci.Application,
|
||||
appFunc func(t *testing.T) abci.Application,
|
||||
configOpts ...func(*config.Config),
|
||||
) ([]*State, cleanupFunc) {
|
||||
|
||||
@@ -786,9 +762,9 @@ func randConsensusState(
|
||||
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 {
|
||||
closeFuncs = append(closeFuncs, appCloser.Close)
|
||||
@@ -798,7 +774,7 @@ func randConsensusState(
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -815,6 +791,7 @@ func randConsensusState(
|
||||
// nPeers = nValidators + nNotValidator
|
||||
func randConsensusNetWithPeers(
|
||||
ctx context.Context,
|
||||
t *testing.T,
|
||||
cfg *config.Config,
|
||||
nValidators int,
|
||||
nPeers int,
|
||||
@@ -822,6 +799,8 @@ func randConsensusNetWithPeers(
|
||||
tickerFunc func() TimeoutTicker,
|
||||
appFunc func(string) abci.Application,
|
||||
) ([]*State, *types.GenesisDoc, *config.Config, cleanupFunc) {
|
||||
t.Helper()
|
||||
|
||||
genDoc, privVals := factory.RandGenesisDoc(ctx, cfg, nValidators, false, testMinPower)
|
||||
css := make([]*State, nPeers)
|
||||
logger := consensusLogger()
|
||||
@@ -831,12 +810,10 @@ func randConsensusNetWithPeers(
|
||||
for i := 0; i < nPeers; i++ {
|
||||
state, _ := sm.MakeGenesisState(genDoc)
|
||||
thisConfig, err := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
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 {
|
||||
peer0Config = thisConfig
|
||||
}
|
||||
@@ -845,18 +822,13 @@ func randConsensusNetWithPeers(
|
||||
privVal = privVals[i]
|
||||
} else {
|
||||
tempKeyFile, err := os.CreateTemp("", "priv_validator_key_")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
tempStateFile, err := os.CreateTemp("", "priv_validator_state_")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
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)))
|
||||
@@ -868,7 +840,7 @@ func randConsensusNetWithPeers(
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
// 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())
|
||||
}
|
||||
return css, genDoc, peer0Config, func() {
|
||||
@@ -940,15 +912,16 @@ func (m *mockTicker) Chan() <-chan timeoutInfo {
|
||||
|
||||
func (*mockTicker) SetLogger(log.Logger) {}
|
||||
|
||||
func newPersistentKVStore() abci.Application {
|
||||
func newPersistentKVStore(t *testing.T) abci.Application {
|
||||
t.Helper()
|
||||
|
||||
dir, err := os.MkdirTemp("", "persistent-kvstore")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
return kvstore.NewPersistentKVStoreApplication(dir)
|
||||
}
|
||||
|
||||
func newKVStore() abci.Application {
|
||||
func newKVStore(_ *testing.T) abci.Application {
|
||||
return kvstore.NewApplication()
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,11 @@ import (
|
||||
)
|
||||
|
||||
// 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) {
|
||||
@@ -38,18 +41,18 @@ func TestMempoolNoProgressUntilTxsAvailable(t *testing.T) {
|
||||
|
||||
config.Consensus.CreateEmptyBlocks = false
|
||||
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
|
||||
newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock)
|
||||
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) {
|
||||
@@ -63,16 +66,16 @@ func TestMempoolProgressAfterCreateEmptyBlocksInterval(t *testing.T) {
|
||||
|
||||
config.Consensus.CreateEmptyBlocksInterval = ensureTimeout
|
||||
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)
|
||||
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) {
|
||||
@@ -86,8 +89,8 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
|
||||
|
||||
config.Consensus.CreateEmptyBlocks = false
|
||||
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
|
||||
newBlockCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlock)
|
||||
newRoundCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewRound)
|
||||
@@ -103,30 +106,29 @@ func TestMempoolProgressInHigherRound(t *testing.T) {
|
||||
}
|
||||
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
|
||||
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.
|
||||
for i := start; i < end; i++ {
|
||||
txBytes := make([]byte, 8)
|
||||
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(
|
||||
ctx,
|
||||
t,
|
||||
logger, config, state, privVals[0], NewCounterApplication(), blockStore)
|
||||
|
||||
err := stateStore.Save(state)
|
||||
@@ -149,7 +152,7 @@ func TestMempoolTxConcurrentWithCommit(t *testing.T) {
|
||||
newBlockHeaderCh := subscribe(ctx, t, cs.eventBus, types.EventQueryNewBlockHeader)
|
||||
|
||||
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)
|
||||
for n := int64(0); n < numTxs; {
|
||||
@@ -172,7 +175,7 @@ func TestMempoolRmBadTx(t *testing.T) {
|
||||
app := NewCounterApplication()
|
||||
stateStore := sm.NewStore(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)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -192,7 +195,7 @@ func TestMempoolRmBadTx(t *testing.T) {
|
||||
// Try to send the tx through the mempool.
|
||||
// CheckTx should not err, but the app should return a bad abci code
|
||||
// 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 {
|
||||
t.Errorf("expected checktx to return bad nonce, got %v", r)
|
||||
return
|
||||
@@ -206,7 +209,7 @@ func TestMempoolRmBadTx(t *testing.T) {
|
||||
|
||||
// check for the tx
|
||||
for {
|
||||
txs := assertMempool(cs.txNotifier).ReapMaxBytesMaxGas(int64(len(txBytes)), -1)
|
||||
txs := assertMempool(t, cs.txNotifier).ReapMaxBytesMaxGas(int64(len(txBytes)), -1)
|
||||
if len(txs) == 0 {
|
||||
emptyMempoolCh <- struct{}{}
|
||||
return
|
||||
|
||||
@@ -184,7 +184,7 @@ func waitForAndValidateBlock(
|
||||
require.NoError(t, validateBlock(newBlock, activeVals))
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
|
||||
@@ -495,7 +495,7 @@ func TestReactorCreatesBlockWhenEmptyBlocksFalse(t *testing.T) {
|
||||
// send a tx
|
||||
require.NoError(
|
||||
t,
|
||||
assertMempool(states[3].txNotifier).CheckTx(
|
||||
assertMempool(t, states[3].txNotifier).CheckTx(
|
||||
ctx,
|
||||
[]byte{1, 2, 3},
|
||||
nil,
|
||||
@@ -703,6 +703,7 @@ func TestReactorValidatorSetChanges(t *testing.T) {
|
||||
nVals := 4
|
||||
states, _, _, cleanup := randConsensusNetWithPeers(
|
||||
ctx,
|
||||
t,
|
||||
cfg,
|
||||
nVals,
|
||||
nPeers,
|
||||
|
||||
@@ -422,9 +422,17 @@ func (h *Handshaker) ReplayBlocks(
|
||||
if err != nil {
|
||||
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")
|
||||
state, err = h.replayBlock(ctx, state, storeBlockHeight, mockApp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return state.AppHash, err
|
||||
}
|
||||
|
||||
|
||||
@@ -61,17 +61,22 @@ func newMockProxyApp(
|
||||
logger log.Logger,
|
||||
appHash []byte,
|
||||
abciResponses *tmstate.ABCIResponses,
|
||||
) proxy.AppConnConsensus {
|
||||
) (proxy.AppConnConsensus, error) {
|
||||
|
||||
clientCreator := abciclient.NewLocalCreator(&mockProxyApp{
|
||||
appHash: appHash,
|
||||
abciResponses: abciResponses,
|
||||
})
|
||||
cli, _ := clientCreator(logger)
|
||||
err := cli.Start(ctx)
|
||||
cli, err := clientCreator(logger)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return proxy.NewAppConnConsensus(cli, proxy.NopMetrics())
|
||||
|
||||
if err = cli.Start(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return proxy.NewAppConnConsensus(cli, proxy.NopMetrics()), nil
|
||||
}
|
||||
|
||||
type mockProxyApp struct {
|
||||
|
||||
@@ -64,6 +64,7 @@ func startNewStateAndWaitForBlock(ctx context.Context, t *testing.T, consensusRe
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
cs := newStateWithConfigAndBlockStore(
|
||||
ctx,
|
||||
t,
|
||||
logger,
|
||||
consensusReplayConfig,
|
||||
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++ {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
default:
|
||||
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++
|
||||
}
|
||||
}
|
||||
@@ -132,7 +134,7 @@ func TestWALCrash(t *testing.T) {
|
||||
1},
|
||||
{"many non-empty blocks",
|
||||
func(stateDB dbm.DB, cs *State, ctx context.Context) {
|
||||
go sendTxs(ctx, cs)
|
||||
go sendTxs(ctx, t, cs)
|
||||
},
|
||||
3},
|
||||
}
|
||||
@@ -168,6 +170,7 @@ LOOP:
|
||||
privValidator := loadPrivValidator(t, consensusReplayConfig)
|
||||
cs := newStateWithConfigAndBlockStore(
|
||||
rctx,
|
||||
t,
|
||||
logger,
|
||||
consensusReplayConfig,
|
||||
state,
|
||||
@@ -334,6 +337,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
|
||||
css, genDoc, cfg, cleanup := randConsensusNetWithPeers(
|
||||
ctx,
|
||||
t,
|
||||
cfg,
|
||||
nVals,
|
||||
nPeers,
|
||||
@@ -361,15 +365,15 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
// start the machine
|
||||
startTestRound(ctx, css[0], height, round)
|
||||
incrementHeight(vss...)
|
||||
ensureNewRound(newRoundCh, height, 0)
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
ensureNewRound(t, newRoundCh, height, 0)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
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(),
|
||||
vss[1:nVals]...)
|
||||
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
// HEIGHT 2
|
||||
height++
|
||||
@@ -379,7 +383,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
valPubKey1ABCI, err := encoding.PubKeyToProto(newValidatorPubKey1)
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
propBlock, _, err := css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
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(),
|
||||
vss[1:nVals]...)
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
// HEIGHT 3
|
||||
height++
|
||||
@@ -413,7 +417,7 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
updatePubKey1ABCI, err := encoding.PubKeyToProto(updateValidatorPubKey1)
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
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(),
|
||||
vss[1:nVals]...)
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
// HEIGHT 4
|
||||
height++
|
||||
@@ -447,14 +451,14 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
newVal2ABCI, err := encoding.PubKeyToProto(newValidatorPubKey2)
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
newValidatorPubKey3, err := css[nVals+2].privValidator.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
newVal3ABCI, err := encoding.PubKeyToProto(newValidatorPubKey3)
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
|
||||
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()}
|
||||
newVss := make([]*validatorStub, nVals+1)
|
||||
copy(newVss, vss[:nVals+1])
|
||||
newVss = sortVValidatorStubsByPower(ctx, newVss)
|
||||
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
|
||||
|
||||
valIndexFn := func(cssIdx int) int {
|
||||
for i, vs := range newVss {
|
||||
@@ -477,10 +481,12 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
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)
|
||||
require.NotEqual(t, -1, selfIndex)
|
||||
|
||||
proposal = types.NewProposal(vss[3].Height, round, -1, blockID)
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
|
||||
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)
|
||||
|
||||
rs = css[0].GetRoundState()
|
||||
@@ -504,38 +510,41 @@ func setupSimulator(ctx context.Context, t *testing.T) *simulatorTestSuite {
|
||||
if i == selfIndex {
|
||||
continue
|
||||
}
|
||||
signAddVotes(ctx, sim.Config, css[0],
|
||||
signAddVotes(ctx, t, sim.Config, css[0],
|
||||
tmproto.PrecommitType, rs.ProposalBlock.Hash(),
|
||||
rs.ProposalBlockParts.Header(), newVss[i])
|
||||
}
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
// HEIGHT 5
|
||||
height++
|
||||
incrementHeight(vss...)
|
||||
// Reflect the changes to vss[nVals] at height 3 and resort newVss.
|
||||
newVssIdx := valIndexFn(nVals)
|
||||
require.NotEqual(t, -1, newVssIdx)
|
||||
|
||||
newVss[newVssIdx].VotingPower = 25
|
||||
newVss = sortVValidatorStubsByPower(ctx, newVss)
|
||||
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
|
||||
|
||||
selfIndex = valIndexFn(0)
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
require.NotEqual(t, -1, selfIndex)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
rs = css[0].GetRoundState()
|
||||
for i := 0; i < nVals+1; i++ {
|
||||
if i == selfIndex {
|
||||
continue
|
||||
}
|
||||
signAddVotes(ctx, sim.Config, css[0],
|
||||
signAddVotes(ctx, t, sim.Config, css[0],
|
||||
tmproto.PrecommitType, rs.ProposalBlock.Hash(),
|
||||
rs.ProposalBlockParts.Header(), newVss[i])
|
||||
}
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
// HEIGHT 6
|
||||
height++
|
||||
incrementHeight(vss...)
|
||||
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)
|
||||
propBlock, _, err = css[0].createProposalBlock() // changeProposer(t, cs1, vs2)
|
||||
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()}
|
||||
newVss = make([]*validatorStub, nVals+3)
|
||||
copy(newVss, vss[:nVals+3])
|
||||
newVss = sortVValidatorStubsByPower(ctx, newVss)
|
||||
newVss = sortVValidatorStubsByPower(ctx, t, newVss)
|
||||
|
||||
selfIndex = valIndexFn(0)
|
||||
require.NotEqual(t, -1, selfIndex)
|
||||
|
||||
proposal = types.NewProposal(vss[1].Height, round, -1, blockID)
|
||||
p = proposal.ToProto()
|
||||
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 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ensureNewProposal(proposalCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
rs = css[0].GetRoundState()
|
||||
for i := 0; i < nVals+3; i++ {
|
||||
if i == selfIndex {
|
||||
continue
|
||||
}
|
||||
signAddVotes(ctx, sim.Config, css[0],
|
||||
signAddVotes(ctx, t, sim.Config, css[0],
|
||||
tmproto.PrecommitType, rs.ProposalBlock.Hash(),
|
||||
rs.ProposalBlockParts.Header(), newVss[i])
|
||||
}
|
||||
ensureNewRound(newRoundCh, height+1, 0)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
|
||||
sim.Chain = make([]*types.Block, 0)
|
||||
sim.Commits = make([]*types.Commit, 0)
|
||||
@@ -670,7 +681,8 @@ func TestMockProxyApp(t *testing.T) {
|
||||
err = proto.Unmarshal(bytes, loadedAbciRes)
|
||||
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.DeliverTxs = make([]*abci.ResponseDeliverTx, len(loadedAbciRes.DeliverTxs))
|
||||
@@ -701,18 +713,17 @@ func TestMockProxyApp(t *testing.T) {
|
||||
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")
|
||||
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)
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -755,7 +766,7 @@ func testHandshakeReplay(
|
||||
defer func() { _ = os.RemoveAll(testConfig.RootDir) }()
|
||||
walBody, err := WALWithNBlocks(ctx, t, numBlocks)
|
||||
require.NoError(t, err)
|
||||
walFile := tempWALWithData(walBody)
|
||||
walFile := tempWALWithData(t, walBody)
|
||||
cfg.Consensus.SetWalFile(walFile)
|
||||
|
||||
privVal, err := privval.LoadFilePV(cfg.PrivValidator.KeyFile(), cfg.PrivValidator.StateFile())
|
||||
@@ -766,8 +777,7 @@ func testHandshakeReplay(
|
||||
err = wal.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
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)
|
||||
require.NoError(t, err)
|
||||
stateDB, genesisState, store = stateAndStore(t, cfg, pubKey, kvstore.ProtocolVersion)
|
||||
@@ -897,21 +907,19 @@ func buildAppStateFromChain(
|
||||
mode uint,
|
||||
blockStore *mockBlockStore,
|
||||
) {
|
||||
t.Helper()
|
||||
// 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
|
||||
validators := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
if _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
|
||||
_, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
|
||||
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 {
|
||||
case 0:
|
||||
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)
|
||||
}
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown mode %v", mode))
|
||||
require.Fail(t, "unknown mode %v", mode)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -949,6 +957,8 @@ func buildTMStateFromChain(
|
||||
mode uint,
|
||||
blockStore *mockBlockStore,
|
||||
) sm.State {
|
||||
t.Helper()
|
||||
|
||||
// run the whole chain against this client to build up the tendermint state
|
||||
kvstoreApp := kvstore.NewPersistentKVStoreApplication(
|
||||
filepath.Join(cfg.DBDir(), fmt.Sprintf("replay_test_%d_%d_t", nBlocks, mode)))
|
||||
@@ -956,20 +966,17 @@ func buildTMStateFromChain(
|
||||
clientCreator := abciclient.NewLocalCreator(kvstoreApp)
|
||||
|
||||
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
|
||||
validators := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
if _, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
|
||||
_, err := proxyApp.Consensus().InitChainSync(ctx, abci.RequestInitChain{
|
||||
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 {
|
||||
case 0:
|
||||
// sync right up
|
||||
@@ -988,7 +995,7 @@ func buildTMStateFromChain(
|
||||
// get the right next appHash but keep the state back
|
||||
applyBlock(ctx, t, stateStore, mempool, evpool, state, chain[len(chain)-1], proxyApp, blockStore)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown mode %v", mode))
|
||||
require.Fail(t, "unknown mode %v", mode)
|
||||
}
|
||||
|
||||
return state
|
||||
@@ -1089,17 +1096,14 @@ func (app *badApp) Commit() abci.ResponseCommit {
|
||||
//--------------------------
|
||||
// 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
|
||||
|
||||
// Search for height marker
|
||||
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()
|
||||
|
||||
// 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()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
piece := readPieceFromWAL(msg)
|
||||
if piece == nil {
|
||||
@@ -1131,25 +1134,20 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
|
||||
if thisBlockParts != nil {
|
||||
var pbb = new(tmproto.Block)
|
||||
bz, err := io.ReadAll(thisBlockParts.GetReader())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = proto.Unmarshal(bz, pbb)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
block, err := types.BlockFromProto(pbb)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NoError(t, proto.Unmarshal(bz, pbb))
|
||||
|
||||
block, err := types.BlockFromProto(pbb)
|
||||
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
|
||||
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)
|
||||
commits = append(commits, thisBlockCommit)
|
||||
height++
|
||||
@@ -1158,9 +1156,7 @@ func makeBlockchainFromWAL(wal WAL) ([]*types.Block, []*types.Commit, error) {
|
||||
thisBlockParts = types.NewPartSetFromHeader(*p)
|
||||
case *types.Part:
|
||||
_, err := thisBlockParts.AddPart(p)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
require.NoError(t, err)
|
||||
case *types.Vote:
|
||||
if p.Type == tmproto.PrecommitType {
|
||||
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
|
||||
bz, err := io.ReadAll(thisBlockParts.GetReader())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
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)
|
||||
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
|
||||
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)
|
||||
commits = append(commits, thisBlockCommit)
|
||||
return blocks, commits, nil
|
||||
return blocks, commits
|
||||
}
|
||||
|
||||
func readPieceFromWAL(msg *TimedWALMessage) interface{} {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ package types
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -21,7 +22,7 @@ func TestMain(m *testing.M) {
|
||||
var err error
|
||||
cfg, err = config.ResetTestRoot("consensus_height_vote_set_test")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
log.Fatal(err)
|
||||
}
|
||||
code := m.Run()
|
||||
os.RemoveAll(cfg.RootDir)
|
||||
@@ -71,11 +72,11 @@ func makeVoteHR(
|
||||
valIndex, round int32,
|
||||
privVals []types.PrivValidator,
|
||||
) *types.Vote {
|
||||
t.Helper()
|
||||
|
||||
privVal := privVals[valIndex]
|
||||
pubKey, err := privVal.GetPubKey(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
randBytes := tmrand.Bytes(tmhash.Size)
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@ func TestWALSearchForEndHeight(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
walFile := tempWALWithData(walBody)
|
||||
walFile := tempWALWithData(t, walBody)
|
||||
|
||||
wal, err := NewWAL(log.TestingLogger(), walFile)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -592,9 +592,7 @@ func makeVote(
|
||||
|
||||
vpb := v.ToProto()
|
||||
err = val.SignVote(ctx, chainID, vpb)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
v.Signature = vpb.Signature
|
||||
return v
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ import (
|
||||
"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)
|
||||
size := 1000
|
||||
msgs := make([]*test.NinOptNative, size)
|
||||
@@ -94,9 +95,7 @@ func iotest(writer protoio.WriteCloser, reader protoio.ReadCloser) error {
|
||||
}
|
||||
i++
|
||||
}
|
||||
if i != size {
|
||||
panic("not enough messages read")
|
||||
}
|
||||
require.NotEqual(t, size, i)
|
||||
if err := reader.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -121,7 +120,7 @@ func TestVarintNormal(t *testing.T) {
|
||||
buf := newBuffer()
|
||||
writer := protoio.NewDelimitedWriter(buf)
|
||||
reader := protoio.NewDelimitedReader(buf, 1024*1024)
|
||||
err := iotest(writer, reader)
|
||||
err := iotest(t, writer, reader)
|
||||
require.NoError(t, err)
|
||||
require.True(t, buf.closed, "did not close buffer")
|
||||
}
|
||||
@@ -130,7 +129,7 @@ func TestVarintNoClose(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
writer := protoio.NewDelimitedWriter(buf)
|
||||
reader := protoio.NewDelimitedReader(buf, 1024*1024)
|
||||
err := iotest(writer, reader)
|
||||
err := iotest(t, writer, reader)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -139,7 +138,7 @@ func TestVarintMaxSize(t *testing.T) {
|
||||
buf := newBuffer()
|
||||
writer := protoio.NewDelimitedWriter(buf)
|
||||
reader := protoio.NewDelimitedReader(buf, 20)
|
||||
err := iotest(writer, reader)
|
||||
err := iotest(t, writer, reader)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,10 @@ import (
|
||||
"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")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
return &types.Vote{
|
||||
Type: tmproto.SignedMsgType(byte(tmproto.PrevoteType)),
|
||||
@@ -58,14 +57,14 @@ var sink interface{}
|
||||
|
||||
func BenchmarkMarshalDelimitedWithMarshalTo(b *testing.B) {
|
||||
msgs := []proto.Message{
|
||||
aVote().ToProto(),
|
||||
aVote(b).ToProto(),
|
||||
}
|
||||
benchmarkMarshalDelimited(b, msgs)
|
||||
}
|
||||
|
||||
func BenchmarkMarshalDelimitedNoMarshalTo(b *testing.B) {
|
||||
msgs := []proto.Message{
|
||||
&excludedMarshalTo{aVote().ToProto()},
|
||||
&excludedMarshalTo{aVote(b).ToProto()},
|
||||
}
|
||||
benchmarkMarshalDelimited(b, msgs)
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestApplyBlock(t *testing.T) {
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, stateDB, _ := makeState(1, 1)
|
||||
state, stateDB, _ := makeState(t, 1, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp.Consensus(),
|
||||
@@ -78,7 +78,7 @@ func TestBeginBlockValidators(t *testing.T) {
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, stateDB, _ := makeState(2, 2)
|
||||
state, stateDB, _ := makeState(t, 2, 2)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
|
||||
prevHash := state.LastBlockID.Hash
|
||||
@@ -144,7 +144,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, stateDB, privVals := makeState(1, 1)
|
||||
state, stateDB, privVals := makeState(t, 1, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
|
||||
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)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, stateDB, _ := makeState(1, 1)
|
||||
state, stateDB, _ := makeState(t, 1, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
|
||||
@@ -452,7 +452,7 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
|
||||
err := proxyApp.Start(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
state, stateDB, _ := makeState(1, 1)
|
||||
state, stateDB, _ := makeState(t, 1, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
|
||||
@@ -107,7 +107,7 @@ func makeValidCommit(
|
||||
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)
|
||||
privVals := make(map[string]types.PrivValidator, nVals)
|
||||
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()
|
||||
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++ {
|
||||
s.LastBlockHeight++
|
||||
s.LastValidators = s.Validators.Copy()
|
||||
if err := stateStore.Save(s); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
require.NoError(t, stateStore.Save(s))
|
||||
}
|
||||
|
||||
return s, stateDB, privVals
|
||||
@@ -189,6 +186,7 @@ func makeHeaderPartsResponsesValPowerChange(
|
||||
state sm.State,
|
||||
power int64,
|
||||
) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
|
||||
t.Helper()
|
||||
|
||||
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
|
||||
require.NoError(t, err)
|
||||
@@ -202,9 +200,8 @@ func makeHeaderPartsResponsesValPowerChange(
|
||||
_, val := state.NextValidators.GetByIndex(0)
|
||||
if val.VotingPower != power {
|
||||
vPbPk, err := encoding.PubKeyToProto(val.PubKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
abciResponses.EndBlock = &abci.ResponseEndBlock{
|
||||
ValidatorUpdates: []abci.ValidatorUpdate{
|
||||
{PubKey: vPbPk, Power: power},
|
||||
@@ -220,6 +217,7 @@ func makeHeaderPartsResponsesParams(
|
||||
state sm.State,
|
||||
params *types.ConsensusParams,
|
||||
) (types.Header, types.BlockID, *tmstate.ABCIResponses) {
|
||||
t.Helper()
|
||||
|
||||
block, err := sf.MakeBlock(state, state.LastBlockHeight+1, new(types.Commit))
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -34,7 +34,7 @@ func TestValidateBlockHeader(t *testing.T) {
|
||||
proxyApp := newTestApp()
|
||||
require.NoError(t, proxyApp.Start(ctx))
|
||||
|
||||
state, stateDB, privVals := makeState(3, 1)
|
||||
state, stateDB, privVals := makeState(t, 3, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
@@ -125,7 +125,7 @@ func TestValidateBlockCommit(t *testing.T) {
|
||||
proxyApp := newTestApp()
|
||||
require.NoError(t, proxyApp.Start(ctx))
|
||||
|
||||
state, stateDB, privVals := makeState(1, 1)
|
||||
state, stateDB, privVals := makeState(t, 1, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
blockExec := sm.NewBlockExecutor(
|
||||
@@ -253,7 +253,7 @@ func TestValidateBlockEvidence(t *testing.T) {
|
||||
proxyApp := newTestApp()
|
||||
require.NoError(t, proxyApp.Start(ctx))
|
||||
|
||||
state, stateDB, privVals := makeState(4, 1)
|
||||
state, stateDB, privVals := makeState(t, 4, 1)
|
||||
stateStore := sm.NewStore(stateDB)
|
||||
blockStore := store.NewBlockStore(dbm.NewMemDB())
|
||||
defaultEvidenceTime := time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
||||
@@ -46,18 +46,18 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit {
|
||||
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")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return sm.State{}, nil, nil, err
|
||||
}
|
||||
|
||||
blockDB := dbm.NewMemDB()
|
||||
state, err := sm.MakeGenesisStateFromFile(cfg.GenesisFile())
|
||||
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) {
|
||||
@@ -77,7 +77,12 @@ var (
|
||||
func TestMain(m *testing.M) {
|
||||
var cleanup cleanupFunc
|
||||
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))
|
||||
|
||||
if err != nil {
|
||||
@@ -97,8 +102,9 @@ func TestMain(m *testing.M) {
|
||||
|
||||
// TODO: This test should be simplified ...
|
||||
func TestBlockStoreSaveLoadBlock(t *testing.T) {
|
||||
state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger())
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(log.NewNopLogger())
|
||||
defer cleanup()
|
||||
require.NoError(t, err)
|
||||
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")
|
||||
|
||||
@@ -488,8 +494,9 @@ func TestLoadBlockMeta(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockFetchAtHeight(t *testing.T) {
|
||||
state, bs, cleanup := makeStateAndBlockStore(log.NewNopLogger())
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(log.NewNopLogger())
|
||||
defer cleanup()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
|
||||
block, err := factory.MakeBlock(state, bs.Height()+1, new(types.Commit))
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -3,7 +3,6 @@ package bits
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
@@ -149,9 +148,8 @@ func TestBytes(t *testing.T) {
|
||||
bA := NewBitArray(4)
|
||||
bA.SetIndex(0, true)
|
||||
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})
|
||||
bA.SetIndex(3, true)
|
||||
|
||||
@@ -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")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
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
|
||||
// the test cases.
|
||||
cval1 := "fubble"
|
||||
conf1 := tempDir()
|
||||
conf1 := tempDir(t)
|
||||
err := WriteConfigVals(conf1, map[string]string{"boo": cval1})
|
||||
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
|
||||
// the test cases.
|
||||
cval1, cval2 := "someone", "else"
|
||||
conf1 := tempDir()
|
||||
conf1 := tempDir(t)
|
||||
err := WriteConfigVals(conf1, map[string]string{"name": cval1})
|
||||
require.NoError(t, err)
|
||||
// even with some ignored fields, should be no problem
|
||||
conf2 := tempDir()
|
||||
conf2 := tempDir(t)
|
||||
err = WriteConfigVals(conf2, map[string]string{"name": cval2, "foo": "bar"})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/fortytw2/leaktest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
@@ -151,6 +152,7 @@ func TestNodeSetAppVersion(t *testing.T) {
|
||||
func TestNodeSetPrivValTCP(t *testing.T) {
|
||||
addr := "tcp://" + testFreeAddr(t)
|
||||
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -173,9 +175,7 @@ func TestNodeSetPrivValTCP(t *testing.T) {
|
||||
|
||||
go func() {
|
||||
err := signerServer.Start(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
}()
|
||||
defer signerServer.Stop() //nolint:errcheck // ignore for tests
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package client_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -26,6 +25,7 @@ func MakeTxKV() ([]byte, []byte, []byte) {
|
||||
}
|
||||
|
||||
func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string, c client.Client) {
|
||||
t.Helper()
|
||||
// make the tx
|
||||
_, _, tx := MakeTxKV()
|
||||
|
||||
@@ -43,7 +43,7 @@ func testTxEventsSent(ctx context.Context, t *testing.T, broadcastMethod string,
|
||||
case "sync":
|
||||
txres, err = c.BroadcastTxSync(ctx, tx)
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown broadcastMethod %s", broadcastMethod))
|
||||
require.FailNowf(t, "Unknown broadcastMethod %s", broadcastMethod)
|
||||
}
|
||||
if assert.NoError(t, err) {
|
||||
assert.Equal(t, txres.Code, abci.CodeTypeOK)
|
||||
|
||||
@@ -20,9 +20,10 @@ import (
|
||||
|
||||
var wsCallTimeout = 5 * time.Second
|
||||
|
||||
type myHandler struct {
|
||||
type myTestHandler struct {
|
||||
closeConnAfterRead bool
|
||||
mtx sync.RWMutex
|
||||
t *testing.T
|
||||
}
|
||||
|
||||
var upgrader = websocket.Upgrader{
|
||||
@@ -30,11 +31,10 @@ var upgrader = websocket.Upgrader{
|
||||
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)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(h.t, err)
|
||||
|
||||
defer conn.Close()
|
||||
for {
|
||||
messageType, in, err := conn.ReadMessage()
|
||||
@@ -44,17 +44,16 @@ func (h *myHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var req rpctypes.RPCRequest
|
||||
err = json.Unmarshal(in, &req)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
require.NoError(h.t, err)
|
||||
|
||||
h.mtx.RLock()
|
||||
if h.closeConnAfterRead {
|
||||
if err := conn.Close(); err != nil {
|
||||
panic(err)
|
||||
func() {
|
||||
h.mtx.RLock()
|
||||
defer h.mtx.RUnlock()
|
||||
|
||||
if h.closeConnAfterRead {
|
||||
require.NoError(h.t, conn.Close())
|
||||
}
|
||||
}
|
||||
h.mtx.RUnlock()
|
||||
}()
|
||||
|
||||
res := json.RawMessage(`{}`)
|
||||
emptyRespBytes, _ := json.Marshal(rpctypes.RPCResponse{Result: res, ID: req.ID})
|
||||
@@ -68,7 +67,7 @@ func TestWSClientReconnectsAfterReadFailure(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
// start server
|
||||
h := &myHandler{}
|
||||
h := &myTestHandler{t: t}
|
||||
s := httptest.NewServer(h)
|
||||
defer s.Close()
|
||||
|
||||
@@ -100,7 +99,7 @@ func TestWSClientReconnectsAfterWriteFailure(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
// start server
|
||||
h := &myHandler{}
|
||||
h := &myTestHandler{t: t}
|
||||
s := httptest.NewServer(h)
|
||||
defer s.Close()
|
||||
|
||||
@@ -130,7 +129,7 @@ func TestWSClientReconnectFailure(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
// start server
|
||||
h := &myHandler{}
|
||||
h := &myTestHandler{t: t}
|
||||
s := httptest.NewServer(h)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -185,7 +184,7 @@ func TestNotBlockingOnStop(t *testing.T) {
|
||||
t.Cleanup(leaktest.Check(t))
|
||||
|
||||
timeout := 3 * time.Second
|
||||
s := httptest.NewServer(&myHandler{})
|
||||
s := httptest.NewServer(&myTestHandler{t: t})
|
||||
defer s.Close()
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
crand "crypto/rand"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
mrand "math/rand"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -84,22 +85,24 @@ func TestMain(m *testing.M) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
setup(ctx)
|
||||
if err := setup(ctx); err != nil {
|
||||
stdlog.Fatal(err.Error())
|
||||
}
|
||||
code := m.Run()
|
||||
os.Exit(code)
|
||||
}
|
||||
|
||||
// launch unix and tcp servers
|
||||
func setup(ctx context.Context) {
|
||||
func setup(ctx context.Context) error {
|
||||
logger := log.MustNewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo, false)
|
||||
|
||||
cmd := exec.Command("rm", "-f", unixSocket)
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
if err = cmd.Wait(); err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
|
||||
tcpLogger := logger.With("socket", "tcp")
|
||||
@@ -111,7 +114,7 @@ func setup(ctx context.Context) {
|
||||
config := server.DefaultConfig()
|
||||
listener1, err := server.Listen(tcpAddr, config.MaxOpenConnections)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
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)
|
||||
listener2, err := server.Listen(unixAddr, config.MaxOpenConnections)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
go func() {
|
||||
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
|
||||
time.Sleep(time.Second * 2)
|
||||
return nil
|
||||
}
|
||||
|
||||
func echoViaHTTP(ctx context.Context, cl client.Caller, val string) (string, error) {
|
||||
|
||||
@@ -37,7 +37,7 @@ func TestValidator_Sets(t *testing.T) {
|
||||
}
|
||||
|
||||
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++ {
|
||||
validators := []*types.Validator{}
|
||||
@@ -52,7 +52,7 @@ func TestValidator_Sets(t *testing.T) {
|
||||
}
|
||||
require.Equal(t, valSchedule.Set.Validators, validators,
|
||||
"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++
|
||||
}
|
||||
}
|
||||
valSchedule.Increment(1)
|
||||
require.NoError(t, valSchedule.Increment(1))
|
||||
}
|
||||
|
||||
require.False(t, proposeCount == 0 && expectCount > 0,
|
||||
@@ -123,7 +123,7 @@ func TestValidator_Sign(t *testing.T) {
|
||||
} else {
|
||||
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,
|
||||
@@ -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++ {
|
||||
s.height++
|
||||
if s.height > 2 {
|
||||
@@ -162,12 +162,13 @@ func (s *validatorSchedule) Increment(heights int64) {
|
||||
// two blocks after they're returned.
|
||||
if update, ok := s.updates[s.height-2]; ok {
|
||||
if err := s.Set.UpdateWithChangeSet(makeVals(update)); err != nil {
|
||||
panic(err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
s.Set.IncrementProposerPriority(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeVals(valMap map[*e2e.Node]int64) []*types.Validator {
|
||||
|
||||
Reference in New Issue
Block a user