You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
6.2 KiB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
  1. package consensus
  2. import (
  3. "bytes"
  4. "testing"
  5. _ "github.com/tendermint/tendermint/config/tendermint_test"
  6. "github.com/tendermint/tendermint/types"
  7. )
  8. func TestSetupRound(t *testing.T) {
  9. cs, privValidators := randConsensusState()
  10. val0 := privValidators[0]
  11. // Add a vote, precommit, and commit by val0.
  12. voteTypes := []byte{types.VoteTypePrevote, types.VoteTypePrecommit, types.VoteTypeCommit}
  13. for _, voteType := range voteTypes {
  14. vote := &types.Vote{Height: 1, Round: 0, Type: voteType} // nil vote
  15. err := val0.SignVote(vote)
  16. if err != nil {
  17. t.Error("Error signing vote: %v", err)
  18. }
  19. cs.AddVote(val0.Address, vote)
  20. }
  21. // Ensure that vote appears in RoundState.
  22. rs0 := cs.GetRoundState()
  23. if vote := rs0.Prevotes.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypePrevote {
  24. t.Errorf("Expected to find prevote but got %v", vote)
  25. }
  26. if vote := rs0.Precommits.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypePrecommit {
  27. t.Errorf("Expected to find precommit but got %v", vote)
  28. }
  29. if vote := rs0.Commits.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypeCommit {
  30. t.Errorf("Expected to find commit but got %v", vote)
  31. }
  32. // Setup round 1 (next round)
  33. cs.SetupNewRound(1, 1)
  34. <-cs.NewStepCh()
  35. // Now the commit should be copied over to prevotes and precommits.
  36. rs1 := cs.GetRoundState()
  37. if vote := rs1.Prevotes.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypeCommit {
  38. t.Errorf("Expected to find commit but got %v", vote)
  39. }
  40. if vote := rs1.Precommits.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypeCommit {
  41. t.Errorf("Expected to find commit but got %v", vote)
  42. }
  43. if vote := rs1.Commits.GetByAddress(val0.Address); vote == nil || vote.Type != types.VoteTypeCommit {
  44. t.Errorf("Expected to find commit but got %v", vote)
  45. }
  46. }
  47. func TestRunActionProposeNoPrivValidator(t *testing.T) {
  48. cs, _ := randConsensusState()
  49. cs.RunActionPropose(1, 0)
  50. rs := cs.GetRoundState()
  51. if rs.Proposal != nil {
  52. t.Error("Expected to make no proposal, since no privValidator")
  53. }
  54. }
  55. func TestRunActionPropose(t *testing.T) {
  56. cs, privValidators := randConsensusState()
  57. val0 := privValidators[0]
  58. cs.SetPrivValidator(val0)
  59. cs.RunActionPropose(1, 0)
  60. rs := cs.GetRoundState()
  61. // Check that Proposal, ProposalBlock, ProposalBlockParts are set.
  62. if rs.Proposal == nil {
  63. t.Error("rs.Proposal should be set")
  64. }
  65. if rs.ProposalBlock == nil {
  66. t.Error("rs.ProposalBlock should be set")
  67. }
  68. if rs.ProposalBlockParts.Total() == 0 {
  69. t.Error("rs.ProposalBlockParts should be set")
  70. }
  71. }
  72. func checkRoundState(t *testing.T, rs *RoundState,
  73. height uint, round uint, step RoundStepType) {
  74. if rs.Height != height {
  75. t.Errorf("rs.Height should be %v, got %v", height, rs.Height)
  76. }
  77. if rs.Round != round {
  78. t.Errorf("rs.Round should be %v, got %v", round, rs.Round)
  79. }
  80. if rs.Step != step {
  81. t.Errorf("rs.Step should be %v, got %v", step, rs.Step)
  82. }
  83. }
  84. func TestRunActionPrecommitCommitFinalize(t *testing.T) {
  85. cs, privValidators := randConsensusState()
  86. val0 := privValidators[0]
  87. cs.SetPrivValidator(val0)
  88. cs.RunActionPrecommit(1, 0)
  89. <-cs.NewStepCh() // TODO: test this value too.
  90. if cs.Precommits.GetByAddress(val0.Address) != nil {
  91. t.Errorf("RunActionPrecommit should return nil without a proposal")
  92. }
  93. cs.RunActionPropose(1, 0)
  94. <-cs.NewStepCh() // TODO: test this value too.
  95. cs.RunActionPrecommit(1, 0)
  96. <-cs.NewStepCh() // TODO: test this value too.
  97. if cs.Precommits.GetByAddress(val0.Address) != nil {
  98. t.Errorf("RunActionPrecommit should return nil, not enough prevotes")
  99. }
  100. // Add at least +2/3 prevotes.
  101. for i := 0; i < 7; i++ {
  102. vote := &types.Vote{
  103. Height: 1,
  104. Round: 0,
  105. Type: types.VoteTypePrevote,
  106. BlockHash: cs.ProposalBlock.Hash(),
  107. BlockParts: cs.ProposalBlockParts.Header(),
  108. }
  109. err := privValidators[i].SignVote(vote)
  110. if err != nil {
  111. t.Error("Error signing vote: %v", err)
  112. }
  113. cs.AddVote(privValidators[i].Address, vote)
  114. }
  115. // Test RunActionPrecommit success:
  116. cs.RunActionPrecommit(1, 0)
  117. <-cs.NewStepCh() // TODO: test this value too.
  118. if cs.Precommits.GetByAddress(val0.Address) == nil {
  119. t.Errorf("RunActionPrecommit should have succeeded")
  120. }
  121. checkRoundState(t, cs.GetRoundState(), 1, 0, RoundStepPrecommit)
  122. // Add at least +2/3 precommits.
  123. for i := 0; i < 7; i++ {
  124. if bytes.Equal(privValidators[i].Address, val0.Address) {
  125. if cs.Precommits.GetByAddress(val0.Address) == nil {
  126. t.Errorf("Proposer should already have signed a precommit vote")
  127. }
  128. continue
  129. }
  130. vote := &types.Vote{
  131. Height: 1,
  132. Round: 0,
  133. Type: types.VoteTypePrecommit,
  134. BlockHash: cs.ProposalBlock.Hash(),
  135. BlockParts: cs.ProposalBlockParts.Header(),
  136. }
  137. err := privValidators[i].SignVote(vote)
  138. if err != nil {
  139. t.Error("Error signing vote: %v", err)
  140. }
  141. added, _, err := cs.AddVote(privValidators[i].Address, vote)
  142. if !added || err != nil {
  143. t.Errorf("Error adding precommit: %v", err)
  144. }
  145. }
  146. // Test RunActionCommit success:
  147. cs.RunActionCommit(1)
  148. <-cs.NewStepCh() // TODO: test this value too.
  149. if cs.Commits.GetByAddress(val0.Address) == nil {
  150. t.Errorf("RunActionCommit should have succeeded")
  151. }
  152. checkRoundState(t, cs.GetRoundState(), 1, 0, RoundStepCommit)
  153. // cs.CommitTime should still be zero
  154. if !cs.CommitTime.IsZero() {
  155. t.Errorf("Expected CommitTime to yet be zero")
  156. }
  157. // Add at least +2/3 commits.
  158. for i := 0; i < 7; i++ {
  159. if bytes.Equal(privValidators[i].Address, val0.Address) {
  160. if cs.Commits.GetByAddress(val0.Address) == nil {
  161. t.Errorf("Proposer should already have signed a commit vote")
  162. }
  163. continue
  164. }
  165. vote := &types.Vote{
  166. Height: 1,
  167. Round: uint(i), // Doesn't matter what round
  168. Type: types.VoteTypeCommit,
  169. BlockHash: cs.ProposalBlock.Hash(),
  170. BlockParts: cs.ProposalBlockParts.Header(),
  171. }
  172. err := privValidators[i].SignVote(vote)
  173. if err != nil {
  174. t.Error("Error signing vote: %v", err)
  175. }
  176. added, _, err := cs.AddVote(privValidators[i].Address, vote)
  177. if !added || err != nil {
  178. t.Errorf("Error adding commit: %v", err)
  179. }
  180. }
  181. // Test TryFinalizeCommit:
  182. cs.TryFinalizeCommit(1)
  183. <-cs.NewStepCh() // TODO: test this value too.
  184. checkRoundState(t, cs.GetRoundState(), 2, 0, RoundStepNewHeight)
  185. }