|
|
|
|
@@ -69,9 +69,10 @@ func configSetup(t *testing.T) *cfg.Config {
|
|
|
|
|
return config
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ensureDir(dir string, mode os.FileMode) {
|
|
|
|
|
func ensureDir(t *testing.T, dir string, mode os.FileMode) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
if err := tmos.EnsureDir(dir, mode); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error opening directory: %s", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -221,18 +222,20 @@ func startTestRound(cs *State, height int64, round int32) {
|
|
|
|
|
|
|
|
|
|
// Create proposal block from cs1 but sign it with vs.
|
|
|
|
|
func decideProposal(
|
|
|
|
|
t *testing.T,
|
|
|
|
|
cs1 *State,
|
|
|
|
|
vs *validatorStub,
|
|
|
|
|
height int64,
|
|
|
|
|
round int32,
|
|
|
|
|
) (proposal *types.Proposal, block *types.Block) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
cs1.mtx.Lock()
|
|
|
|
|
block, blockParts := cs1.createProposalBlock()
|
|
|
|
|
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?")
|
|
|
|
|
t.Fatal("Failed to createProposalBlock. Did you forget to add commit for previous block?")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make proposal
|
|
|
|
|
@@ -240,7 +243,7 @@ func decideProposal(
|
|
|
|
|
proposal = types.NewProposal(height, round, polRound, propBlockID)
|
|
|
|
|
p := proposal.ToProto()
|
|
|
|
|
if err := vs.SignProposal(context.Background(), chainID, p); err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error signing proposal: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
proposal.Signature = p.Signature
|
|
|
|
|
@@ -267,36 +270,38 @@ func signAddVotes(
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validatePrevote(t *testing.T, cs *State, round int32, privVal *validatorStub, blockHash []byte) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
prevotes := cs.Votes.Prevotes(round)
|
|
|
|
|
pubKey, err := privVal.GetPubKey(context.Background())
|
|
|
|
|
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")
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("Expected prevote to be for %X, got %X", blockHash, vote.BlockID.Hash)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func validateLastPrecommit(t *testing.T, cs *State, privVal *validatorStub, blockHash []byte) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
votes := cs.LastCommit
|
|
|
|
|
pv, err := privVal.GetPubKey(context.Background())
|
|
|
|
|
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")
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("Expected precommit to be for %X, got %X", blockHash, vote.BlockID.Hash)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -309,41 +314,42 @@ func validatePrecommit(
|
|
|
|
|
votedBlockHash,
|
|
|
|
|
lockedBlockHash []byte,
|
|
|
|
|
) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
precommits := cs.Votes.Precommits(thisRound)
|
|
|
|
|
pv, err := privVal.GetPubKey(context.Background())
|
|
|
|
|
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")
|
|
|
|
|
t.Fatalf("Failed to find precommit from validator")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if votedBlockHash == nil {
|
|
|
|
|
if vote.BlockID.Hash != nil {
|
|
|
|
|
panic("Expected precommit to be for nil")
|
|
|
|
|
t.Fatalf("Expected precommit to be for nil")
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if !bytes.Equal(vote.BlockID.Hash, votedBlockHash) {
|
|
|
|
|
panic("Expected precommit to be for proposal block")
|
|
|
|
|
t.Fatalf("Expected precommit to be for proposal block")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if lockedBlockHash == nil {
|
|
|
|
|
if cs.LockedRound != lockRound || cs.LockedBlock != nil {
|
|
|
|
|
panic(fmt.Sprintf(
|
|
|
|
|
t.Fatalf(
|
|
|
|
|
"Expected to be locked on nil at round %d. Got locked at round %d with block %v",
|
|
|
|
|
lockRound,
|
|
|
|
|
cs.LockedRound,
|
|
|
|
|
cs.LockedBlock))
|
|
|
|
|
cs.LockedBlock)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash) {
|
|
|
|
|
panic(fmt.Sprintf(
|
|
|
|
|
t.Fatalf(
|
|
|
|
|
"Expected block to be locked on round %d, got %d. Got locked block %X, expected %X",
|
|
|
|
|
lockRound,
|
|
|
|
|
cs.LockedRound,
|
|
|
|
|
cs.LockedBlock.Hash(),
|
|
|
|
|
lockedBlockHash))
|
|
|
|
|
lockedBlockHash)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -357,6 +363,7 @@ func validatePrevoteAndPrecommit(
|
|
|
|
|
votedBlockHash,
|
|
|
|
|
lockedBlockHash []byte,
|
|
|
|
|
) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
// verify the prevote
|
|
|
|
|
validatePrevote(t, cs, thisRound, privVal, votedBlockHash)
|
|
|
|
|
// verify precommit
|
|
|
|
|
@@ -444,13 +451,14 @@ func newStateWithConfigAndBlockStore(
|
|
|
|
|
return cs
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func loadPrivValidator(config *cfg.Config) *privval.FilePV {
|
|
|
|
|
func loadPrivValidator(t *testing.T, config *cfg.Config) *privval.FilePV {
|
|
|
|
|
t.Helper()
|
|
|
|
|
privValidatorKeyFile := config.PrivValidator.KeyFile()
|
|
|
|
|
ensureDir(filepath.Dir(privValidatorKeyFile), 0700)
|
|
|
|
|
ensureDir(t, filepath.Dir(privValidatorKeyFile), 0700)
|
|
|
|
|
privValidatorStateFile := config.PrivValidator.StateFile()
|
|
|
|
|
privValidator, err := privval.LoadOrGenFilePV(privValidatorKeyFile, privValidatorStateFile)
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error generating validator file: %s", err)
|
|
|
|
|
}
|
|
|
|
|
privValidator.Reset()
|
|
|
|
|
return privValidator
|
|
|
|
|
@@ -475,220 +483,241 @@ func randState(config *cfg.Config, nValidators int) (*State, []*validatorStub) {
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
func ensureNoNewEvent(ch <-chan tmpubsub.Message, timeout time.Duration,
|
|
|
|
|
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.Fatalf("unexpected event: %s", errorMessage)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func ensureNoNewEventOnChannel(ch <-chan tmpubsub.Message) {
|
|
|
|
|
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) {
|
|
|
|
|
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(
|
|
|
|
|
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) { //nolint: lll
|
|
|
|
|
t.Helper()
|
|
|
|
|
select {
|
|
|
|
|
case <-time.After(timeout):
|
|
|
|
|
panic(errorMessage)
|
|
|
|
|
t.Fatalf("timed out waiting for new event: %s", 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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", height, roundStateEvent.Height)
|
|
|
|
|
}
|
|
|
|
|
if roundStateEvent.Round != round {
|
|
|
|
|
panic(fmt.Sprintf("expected round %v, got %v", round, roundStateEvent.Round))
|
|
|
|
|
t.Fatalf("expected round %v, got %v", 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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", height, newRoundEvent.Height)
|
|
|
|
|
}
|
|
|
|
|
if newRoundEvent.Round != round {
|
|
|
|
|
panic(fmt.Sprintf("expected round %v, got %v", round, newRoundEvent.Round))
|
|
|
|
|
t.Fatalf("expected round %v, got %v", 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.Fatalf("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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", height, proposalEvent.Height)
|
|
|
|
|
}
|
|
|
|
|
if proposalEvent.Round != round {
|
|
|
|
|
panic(fmt.Sprintf("expected round %v, got %v", round, proposalEvent.Round))
|
|
|
|
|
t.Fatalf("expected round %v, got %v", 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.Fatalf("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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", 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.Fatalf("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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("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()))
|
|
|
|
|
t.Fatalf("expected header %X, got %X", blockHash, blockHeaderEvent.Header.Hash())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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.Fatalf("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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", height, proposalEvent.Height)
|
|
|
|
|
}
|
|
|
|
|
if proposalEvent.Round != round {
|
|
|
|
|
panic(fmt.Sprintf("expected round %v, got %v", round, proposalEvent.Round))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("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,
|
|
|
|
|
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.Fatalf("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()))
|
|
|
|
|
t.Fatalf("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))
|
|
|
|
|
t.Fatalf("expected height %v, got %v", height, vote.Height)
|
|
|
|
|
}
|
|
|
|
|
if vote.Round != round {
|
|
|
|
|
panic(fmt.Sprintf("expected round %v, got %v", round, vote.Round))
|
|
|
|
|
t.Fatalf("expected round %v, got %v", round, vote.Round)
|
|
|
|
|
}
|
|
|
|
|
if vote.Type != voteType {
|
|
|
|
|
panic(fmt.Sprintf("expected type %v, got %v", voteType, vote.Type))
|
|
|
|
|
t.Fatalf("expected type %v, got %v", 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.Fatalf("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.Fatalf("Timeout expired while waiting for new activity on the channel")
|
|
|
|
|
case <-ch:
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -711,6 +740,7 @@ func randConsensusState(
|
|
|
|
|
appFunc func() abci.Application,
|
|
|
|
|
configOpts ...func(*cfg.Config),
|
|
|
|
|
) ([]*State, cleanupFunc) {
|
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
|
|
genDoc, privVals := factory.RandGenesisDoc(config, nValidators, false, 30)
|
|
|
|
|
css := make([]*State, nValidators)
|
|
|
|
|
@@ -731,7 +761,7 @@ 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()
|
|
|
|
|
|
|
|
|
|
@@ -759,6 +789,7 @@ func randConsensusState(
|
|
|
|
|
|
|
|
|
|
// nPeers = nValidators + nNotValidator
|
|
|
|
|
func randConsensusNetWithPeers(
|
|
|
|
|
t *testing.T,
|
|
|
|
|
config *cfg.Config,
|
|
|
|
|
nValidators,
|
|
|
|
|
nPeers int,
|
|
|
|
|
@@ -768,6 +799,7 @@ func randConsensusNetWithPeers(
|
|
|
|
|
) ([]*State, *types.GenesisDoc, *cfg.Config, cleanupFunc) {
|
|
|
|
|
genDoc, privVals := factory.RandGenesisDoc(config, nValidators, false, testMinPower)
|
|
|
|
|
css := make([]*State, nPeers)
|
|
|
|
|
t.Helper()
|
|
|
|
|
logger := consensusLogger()
|
|
|
|
|
|
|
|
|
|
var peer0Config *cfg.Config
|
|
|
|
|
@@ -776,7 +808,7 @@ func randConsensusNetWithPeers(
|
|
|
|
|
state, _ := sm.MakeGenesisState(genDoc)
|
|
|
|
|
thisConfig := ResetConfig(fmt.Sprintf("%s_%d", testName, i))
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
@@ -786,16 +818,16 @@ func randConsensusNetWithPeers(
|
|
|
|
|
} else {
|
|
|
|
|
tempKeyFile, err := ioutil.TempFile("", "priv_validator_key_")
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error creating temp file for validator key: %s", err)
|
|
|
|
|
}
|
|
|
|
|
tempStateFile, err := ioutil.TempFile("", "priv_validator_state_")
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error loading validator state: %s", err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
privVal, err = privval.GenFilePV(tempKeyFile.Name(), tempStateFile.Name(), "")
|
|
|
|
|
if err != nil {
|
|
|
|
|
panic(err)
|
|
|
|
|
t.Fatalf("error generating validator key: %s", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|