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.

335 lines
10 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
10 years ago
10 years ago
10 years ago
10 years ago
  1. package consensus
  2. import (
  3. "bytes"
  4. . "github.com/tendermint/tendermint/blocks"
  5. . "github.com/tendermint/tendermint/common"
  6. . "github.com/tendermint/tendermint/common/test"
  7. "testing"
  8. )
  9. // NOTE: see consensus/test.go for common test methods.
  10. func TestAddVote(t *testing.T) {
  11. height, round := uint32(1), uint16(0)
  12. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
  13. // t.Logf(">> %v", voteSet)
  14. if voteSet.GetById(0) != nil {
  15. t.Errorf("Expected GetById(0) to be nil")
  16. }
  17. if voteSet.BitArray().GetIndex(0) {
  18. t.Errorf("Expected BitArray.GetIndex(0) to be false")
  19. }
  20. hash, header, ok := voteSet.TwoThirdsMajority()
  21. if hash != nil || !header.IsZero() || ok {
  22. t.Errorf("There should be no 2/3 majority")
  23. }
  24. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
  25. privAccounts[0].Sign(vote)
  26. voteSet.Add(vote)
  27. if voteSet.GetById(0) == nil {
  28. t.Errorf("Expected GetById(0) to be present")
  29. }
  30. if !voteSet.BitArray().GetIndex(0) {
  31. t.Errorf("Expected BitArray.GetIndex(0) to be true")
  32. }
  33. hash, header, ok = voteSet.TwoThirdsMajority()
  34. if hash != nil || !header.IsZero() || ok {
  35. t.Errorf("There should be no 2/3 majority")
  36. }
  37. }
  38. func Test2_3Majority(t *testing.T) {
  39. height, round := uint32(1), uint16(0)
  40. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
  41. // 6 out of 10 voted for nil.
  42. voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
  43. for i := 0; i < 6; i++ {
  44. vote := voteProto.Copy()
  45. privAccounts[i].Sign(vote)
  46. voteSet.Add(vote)
  47. }
  48. hash, header, ok := voteSet.TwoThirdsMajority()
  49. if hash != nil || !header.IsZero() || ok {
  50. t.Errorf("There should be no 2/3 majority")
  51. }
  52. // 7th validator voted for some blockhash
  53. {
  54. vote := voteProto.Copy()
  55. vote.BlockHash = CRandBytes(32)
  56. privAccounts[6].Sign(vote)
  57. voteSet.Add(vote)
  58. hash, header, ok = voteSet.TwoThirdsMajority()
  59. if hash != nil || !header.IsZero() || ok {
  60. t.Errorf("There should be no 2/3 majority")
  61. }
  62. }
  63. // 8th validator voted for nil.
  64. {
  65. vote := voteProto.Copy()
  66. vote.BlockHash = nil
  67. privAccounts[7].Sign(vote)
  68. voteSet.Add(vote)
  69. hash, header, ok = voteSet.TwoThirdsMajority()
  70. if hash != nil || !header.IsZero() || !ok {
  71. t.Errorf("There should be 2/3 majority for nil")
  72. }
  73. }
  74. }
  75. func Test2_3MajorityRedux(t *testing.T) {
  76. height, round := uint32(1), uint16(0)
  77. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypePrevote, 100, 1)
  78. blockHash := CRandBytes(32)
  79. blockPartsTotal := uint16(123)
  80. blockParts := PartSetHeader{blockPartsTotal, CRandBytes(32)}
  81. // 66 out of 100 voted for nil.
  82. voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: blockParts}
  83. for i := 0; i < 66; i++ {
  84. vote := voteProto.Copy()
  85. privAccounts[i].Sign(vote)
  86. voteSet.Add(vote)
  87. }
  88. hash, header, ok := voteSet.TwoThirdsMajority()
  89. if hash != nil || !header.IsZero() || ok {
  90. t.Errorf("There should be no 2/3 majority")
  91. }
  92. // 67th validator voted for nil
  93. {
  94. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil, BlockParts: PartSetHeader{}}
  95. privAccounts[66].Sign(vote)
  96. voteSet.Add(vote)
  97. hash, header, ok = voteSet.TwoThirdsMajority()
  98. if hash != nil || !header.IsZero() || ok {
  99. t.Errorf("There should be no 2/3 majority: last vote added was nil")
  100. }
  101. }
  102. // 68th validator voted for a different BlockParts PartSetHeader
  103. {
  104. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal, CRandBytes(32)}}
  105. privAccounts[67].Sign(vote)
  106. voteSet.Add(vote)
  107. hash, header, ok = voteSet.TwoThirdsMajority()
  108. if hash != nil || !header.IsZero() || ok {
  109. t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash")
  110. }
  111. }
  112. // 69th validator voted for different BlockParts Total
  113. {
  114. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: blockHash, BlockParts: PartSetHeader{blockPartsTotal + 1, blockParts.Hash}}
  115. privAccounts[68].Sign(vote)
  116. voteSet.Add(vote)
  117. hash, header, ok = voteSet.TwoThirdsMajority()
  118. if hash != nil || !header.IsZero() || ok {
  119. t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total")
  120. }
  121. }
  122. // 70th validator voted for different BlockHash
  123. {
  124. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32), BlockParts: blockParts}
  125. privAccounts[69].Sign(vote)
  126. voteSet.Add(vote)
  127. hash, header, ok = voteSet.TwoThirdsMajority()
  128. if hash != nil || !header.IsZero() || ok {
  129. t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
  130. }
  131. }
  132. // 71st validator voted for the right BlockHash & BlockParts
  133. {
  134. vote := voteProto.Copy()
  135. privAccounts[70].Sign(vote)
  136. voteSet.Add(vote)
  137. hash, header, ok = voteSet.TwoThirdsMajority()
  138. if !bytes.Equal(hash, blockHash) || !header.Equals(blockParts) || !ok {
  139. t.Errorf("There should be 2/3 majority")
  140. }
  141. }
  142. }
  143. func TestBadVotes(t *testing.T) {
  144. height, round := uint32(1), uint16(0)
  145. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
  146. // val0 votes for nil.
  147. vote := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
  148. privAccounts[0].Sign(vote)
  149. added, _, err := voteSet.Add(vote)
  150. if !added || err != nil {
  151. t.Errorf("Expected Add(vote) to succeed")
  152. }
  153. // val0 votes again for some block.
  154. vote = &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: CRandBytes(32)}
  155. privAccounts[0].Sign(vote)
  156. added, _, err = voteSet.Add(vote)
  157. if added || err == nil {
  158. t.Errorf("Expected Add(vote) to fail, dupeout.")
  159. }
  160. // val1 votes on another height
  161. vote = &Vote{Height: height + 1, Round: round, Type: VoteTypePrevote, BlockHash: nil}
  162. privAccounts[1].Sign(vote)
  163. added, _, err = voteSet.Add(vote)
  164. if added {
  165. t.Errorf("Expected Add(vote) to fail, wrong height")
  166. }
  167. // val2 votes on another round
  168. vote = &Vote{Height: height, Round: round + 1, Type: VoteTypePrevote, BlockHash: nil}
  169. privAccounts[2].Sign(vote)
  170. added, _, err = voteSet.Add(vote)
  171. if added {
  172. t.Errorf("Expected Add(vote) to fail, wrong round")
  173. }
  174. // val3 votes of another type.
  175. vote = &Vote{Height: height, Round: round, Type: VoteTypePrecommit, BlockHash: nil}
  176. privAccounts[3].Sign(vote)
  177. added, _, err = voteSet.Add(vote)
  178. if added {
  179. t.Errorf("Expected Add(vote) to fail, wrong type")
  180. }
  181. }
  182. func TestAddCommitsToPrevoteVotes(t *testing.T) {
  183. height, round := uint32(2), uint16(5)
  184. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypePrevote, 10, 1)
  185. // val0, val1, val2, val3, val4, val5 vote for nil.
  186. voteProto := &Vote{Height: height, Round: round, Type: VoteTypePrevote, BlockHash: nil}
  187. for i := 0; i < 6; i++ {
  188. vote := voteProto.Copy()
  189. privAccounts[i].Sign(vote)
  190. voteSet.Add(vote)
  191. }
  192. hash, header, ok := voteSet.TwoThirdsMajority()
  193. if hash != nil || !header.IsZero() || ok {
  194. t.Errorf("There should be no 2/3 majority")
  195. }
  196. // Attempt to add a commit from val6 at a previous height
  197. vote := &Vote{Height: height - 1, Round: round, Type: VoteTypeCommit, BlockHash: nil}
  198. privAccounts[6].Sign(vote)
  199. added, _, _ := voteSet.Add(vote)
  200. if added {
  201. t.Errorf("Expected Add(vote) to fail, wrong height.")
  202. }
  203. // Attempt to add a commit from val6 at a later round
  204. vote = &Vote{Height: height, Round: round + 1, Type: VoteTypeCommit, BlockHash: nil}
  205. privAccounts[6].Sign(vote)
  206. added, _, _ = voteSet.Add(vote)
  207. if added {
  208. t.Errorf("Expected Add(vote) to fail, cannot add future round vote.")
  209. }
  210. // Attempt to add a commit from val6 for currrent height/round.
  211. vote = &Vote{Height: height, Round: round, Type: VoteTypeCommit, BlockHash: nil}
  212. privAccounts[6].Sign(vote)
  213. added, _, err := voteSet.Add(vote)
  214. if added || err == nil {
  215. t.Errorf("Expected Add(vote) to fail, only prior round commits can be added.")
  216. }
  217. // Add commit from val6 at a previous round
  218. vote = &Vote{Height: height, Round: round - 1, Type: VoteTypeCommit, BlockHash: nil}
  219. privAccounts[6].Sign(vote)
  220. added, _, err = voteSet.Add(vote)
  221. if !added || err != nil {
  222. t.Errorf("Expected Add(vote) to succeed, commit for prior rounds are relevant.")
  223. }
  224. // Also add commit from val7 for previous round.
  225. vote = &Vote{Height: height, Round: round - 2, Type: VoteTypeCommit, BlockHash: nil}
  226. privAccounts[7].Sign(vote)
  227. added, _, err = voteSet.Add(vote)
  228. if !added || err != nil {
  229. t.Errorf("Expected Add(vote) to succeed. err: %v", err)
  230. }
  231. // We should have 2/3 majority
  232. hash, header, ok = voteSet.TwoThirdsMajority()
  233. if hash != nil || !header.IsZero() || !ok {
  234. t.Errorf("There should be 2/3 majority for nil")
  235. }
  236. }
  237. func TestMakeValidation(t *testing.T) {
  238. height, round := uint32(1), uint16(0)
  239. voteSet, _, privAccounts := makeVoteSet(height, round, VoteTypeCommit, 10, 1)
  240. blockHash, blockParts := CRandBytes(32), PartSetHeader{123, CRandBytes(32)}
  241. // 6 out of 10 voted for some block.
  242. voteProto := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
  243. BlockHash: blockHash, BlockParts: blockParts}
  244. for i := 0; i < 6; i++ {
  245. vote := voteProto.Copy()
  246. privAccounts[i].Sign(vote)
  247. voteSet.Add(vote)
  248. }
  249. // MakeValidation should fail.
  250. AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeValidation() })
  251. // 7th voted for some other block.
  252. {
  253. vote := &Vote{Height: height, Round: round, Type: VoteTypeCommit,
  254. BlockHash: CRandBytes(32),
  255. BlockParts: PartSetHeader{123, CRandBytes(32)}}
  256. privAccounts[6].Sign(vote)
  257. voteSet.Add(vote)
  258. }
  259. // The 8th voted like everyone else.
  260. {
  261. vote := voteProto.Copy()
  262. privAccounts[7].Sign(vote)
  263. voteSet.Add(vote)
  264. }
  265. validation := voteSet.MakeValidation()
  266. // Validation should have 10 elements
  267. if len(validation.Commits) != 10 {
  268. t.Errorf("Validation Commits should have the same number of commits as validators")
  269. }
  270. // Ensure that Validation commits are ordered.
  271. for i, rsig := range validation.Commits {
  272. if i < 6 || i == 7 {
  273. if rsig.Round != round {
  274. t.Errorf("Expected round %v but got %v", round, rsig.Round)
  275. }
  276. if rsig.SignerId != uint64(i) {
  277. t.Errorf("Validation commit signer out of order. Expected %v, got %v", i, rsig.Signature)
  278. }
  279. vote := &Vote{Height: height, Round: rsig.Round, Type: VoteTypeCommit,
  280. BlockHash: blockHash, BlockParts: blockParts,
  281. Signature: rsig.Signature}
  282. if !privAccounts[i].Verify(vote) {
  283. t.Errorf("Validation commit did not verify")
  284. }
  285. } else {
  286. if !rsig.IsZero() {
  287. t.Errorf("Expected zero RoundSignature for the rest")
  288. }
  289. }
  290. }
  291. }