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.

474 lines
14 KiB

10 years ago
10 years ago
10 years ago
10 years ago
7 years ago
7 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 types
  2. import (
  3. "bytes"
  4. "testing"
  5. "github.com/tendermint/go-crypto"
  6. cmn "github.com/tendermint/tmlibs/common"
  7. tst "github.com/tendermint/tmlibs/test"
  8. )
  9. // NOTE: privValidators are in order
  10. func randVoteSet(height int, round int, type_ byte, numValidators int, votingPower int64) (*VoteSet, *ValidatorSet, []*PrivValidatorFS) {
  11. valSet, privValidators := RandValidatorSet(numValidators, votingPower)
  12. return NewVoteSet("test_chain_id", height, round, type_, valSet), valSet, privValidators
  13. }
  14. // Convenience: Return new vote with different validator address/index
  15. func withValidator(vote *Vote, addr []byte, idx int) *Vote {
  16. vote = vote.Copy()
  17. vote.ValidatorAddress = addr
  18. vote.ValidatorIndex = idx
  19. return vote
  20. }
  21. // Convenience: Return new vote with different height
  22. func withHeight(vote *Vote, height int) *Vote {
  23. vote = vote.Copy()
  24. vote.Height = height
  25. return vote
  26. }
  27. // Convenience: Return new vote with different round
  28. func withRound(vote *Vote, round int) *Vote {
  29. vote = vote.Copy()
  30. vote.Round = round
  31. return vote
  32. }
  33. // Convenience: Return new vote with different type
  34. func withType(vote *Vote, type_ byte) *Vote {
  35. vote = vote.Copy()
  36. vote.Type = type_
  37. return vote
  38. }
  39. // Convenience: Return new vote with different blockHash
  40. func withBlockHash(vote *Vote, blockHash []byte) *Vote {
  41. vote = vote.Copy()
  42. vote.BlockID.Hash = blockHash
  43. return vote
  44. }
  45. // Convenience: Return new vote with different blockParts
  46. func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote {
  47. vote = vote.Copy()
  48. vote.BlockID.PartsHeader = blockPartsHeader
  49. return vote
  50. }
  51. func signAddVote(privVal *PrivValidatorFS, vote *Vote, voteSet *VoteSet) (bool, error) {
  52. var err error
  53. vote.Signature, err = privVal.Signer.Sign(SignBytes(voteSet.ChainID(), vote))
  54. if err != nil {
  55. return false, err
  56. }
  57. added, err := voteSet.AddVote(vote)
  58. return added, err
  59. }
  60. func TestAddVote(t *testing.T) {
  61. height, round := 1, 0
  62. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
  63. val0 := privValidators[0]
  64. // t.Logf(">> %v", voteSet)
  65. if voteSet.GetByAddress(val0.GetAddress()) != nil {
  66. t.Errorf("Expected GetByAddress(val0.Address) to be nil")
  67. }
  68. if voteSet.BitArray().GetIndex(0) {
  69. t.Errorf("Expected BitArray.GetIndex(0) to be false")
  70. }
  71. blockID, ok := voteSet.TwoThirdsMajority()
  72. if ok || !blockID.IsZero() {
  73. t.Errorf("There should be no 2/3 majority")
  74. }
  75. vote := &Vote{
  76. ValidatorAddress: val0.GetAddress(),
  77. ValidatorIndex: 0, // since privValidators are in order
  78. Height: height,
  79. Round: round,
  80. Type: VoteTypePrevote,
  81. BlockID: BlockID{nil, PartSetHeader{}},
  82. }
  83. _, err := signAddVote(val0, vote, voteSet)
  84. if err != nil {
  85. t.Error(err)
  86. }
  87. if voteSet.GetByAddress(val0.GetAddress()) == nil {
  88. t.Errorf("Expected GetByAddress(val0.Address) to be present")
  89. }
  90. if !voteSet.BitArray().GetIndex(0) {
  91. t.Errorf("Expected BitArray.GetIndex(0) to be true")
  92. }
  93. blockID, ok = voteSet.TwoThirdsMajority()
  94. if ok || !blockID.IsZero() {
  95. t.Errorf("There should be no 2/3 majority")
  96. }
  97. }
  98. func Test2_3Majority(t *testing.T) {
  99. height, round := 1, 0
  100. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
  101. voteProto := &Vote{
  102. ValidatorAddress: nil, // NOTE: must fill in
  103. ValidatorIndex: -1, // NOTE: must fill in
  104. Height: height,
  105. Round: round,
  106. Type: VoteTypePrevote,
  107. BlockID: BlockID{nil, PartSetHeader{}},
  108. }
  109. // 6 out of 10 voted for nil.
  110. for i := 0; i < 6; i++ {
  111. vote := withValidator(voteProto, privValidators[i].GetAddress(), i)
  112. signAddVote(privValidators[i], vote, voteSet)
  113. }
  114. blockID, ok := voteSet.TwoThirdsMajority()
  115. if ok || !blockID.IsZero() {
  116. t.Errorf("There should be no 2/3 majority")
  117. }
  118. // 7th validator voted for some blockhash
  119. {
  120. vote := withValidator(voteProto, privValidators[6].GetAddress(), 6)
  121. signAddVote(privValidators[6], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
  122. blockID, ok = voteSet.TwoThirdsMajority()
  123. if ok || !blockID.IsZero() {
  124. t.Errorf("There should be no 2/3 majority")
  125. }
  126. }
  127. // 8th validator voted for nil.
  128. {
  129. vote := withValidator(voteProto, privValidators[7].GetAddress(), 7)
  130. signAddVote(privValidators[7], vote, voteSet)
  131. blockID, ok = voteSet.TwoThirdsMajority()
  132. if !ok || !blockID.IsZero() {
  133. t.Errorf("There should be 2/3 majority for nil")
  134. }
  135. }
  136. }
  137. func Test2_3MajorityRedux(t *testing.T) {
  138. height, round := 1, 0
  139. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 100, 1)
  140. blockHash := crypto.CRandBytes(32)
  141. blockPartsTotal := 123
  142. blockPartsHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}
  143. voteProto := &Vote{
  144. ValidatorAddress: nil, // NOTE: must fill in
  145. ValidatorIndex: -1, // NOTE: must fill in
  146. Height: height,
  147. Round: round,
  148. Type: VoteTypePrevote,
  149. BlockID: BlockID{blockHash, blockPartsHeader},
  150. }
  151. // 66 out of 100 voted for nil.
  152. for i := 0; i < 66; i++ {
  153. vote := withValidator(voteProto, privValidators[i].GetAddress(), i)
  154. signAddVote(privValidators[i], vote, voteSet)
  155. }
  156. blockID, ok := voteSet.TwoThirdsMajority()
  157. if ok || !blockID.IsZero() {
  158. t.Errorf("There should be no 2/3 majority")
  159. }
  160. // 67th validator voted for nil
  161. {
  162. vote := withValidator(voteProto, privValidators[66].GetAddress(), 66)
  163. signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet)
  164. blockID, ok = voteSet.TwoThirdsMajority()
  165. if ok || !blockID.IsZero() {
  166. t.Errorf("There should be no 2/3 majority: last vote added was nil")
  167. }
  168. }
  169. // 68th validator voted for a different BlockParts PartSetHeader
  170. {
  171. vote := withValidator(voteProto, privValidators[67].GetAddress(), 67)
  172. blockPartsHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}
  173. signAddVote(privValidators[67], withBlockPartsHeader(vote, blockPartsHeader), voteSet)
  174. blockID, ok = voteSet.TwoThirdsMajority()
  175. if ok || !blockID.IsZero() {
  176. t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Hash")
  177. }
  178. }
  179. // 69th validator voted for different BlockParts Total
  180. {
  181. vote := withValidator(voteProto, privValidators[68].GetAddress(), 68)
  182. blockPartsHeader := PartSetHeader{blockPartsTotal + 1, blockPartsHeader.Hash}
  183. signAddVote(privValidators[68], withBlockPartsHeader(vote, blockPartsHeader), voteSet)
  184. blockID, ok = voteSet.TwoThirdsMajority()
  185. if ok || !blockID.IsZero() {
  186. t.Errorf("There should be no 2/3 majority: last vote added had different PartSetHeader Total")
  187. }
  188. }
  189. // 70th validator voted for different BlockHash
  190. {
  191. vote := withValidator(voteProto, privValidators[69].GetAddress(), 69)
  192. signAddVote(privValidators[69], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
  193. blockID, ok = voteSet.TwoThirdsMajority()
  194. if ok || !blockID.IsZero() {
  195. t.Errorf("There should be no 2/3 majority: last vote added had different BlockHash")
  196. }
  197. }
  198. // 71st validator voted for the right BlockHash & BlockPartsHeader
  199. {
  200. vote := withValidator(voteProto, privValidators[70].GetAddress(), 70)
  201. signAddVote(privValidators[70], vote, voteSet)
  202. blockID, ok = voteSet.TwoThirdsMajority()
  203. if !ok || !blockID.Equals(BlockID{blockHash, blockPartsHeader}) {
  204. t.Errorf("There should be 2/3 majority")
  205. }
  206. }
  207. }
  208. func TestBadVotes(t *testing.T) {
  209. height, round := 1, 0
  210. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 10, 1)
  211. voteProto := &Vote{
  212. ValidatorAddress: nil,
  213. ValidatorIndex: -1,
  214. Height: height,
  215. Round: round,
  216. Type: VoteTypePrevote,
  217. BlockID: BlockID{nil, PartSetHeader{}},
  218. }
  219. // val0 votes for nil.
  220. {
  221. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  222. added, err := signAddVote(privValidators[0], vote, voteSet)
  223. if !added || err != nil {
  224. t.Errorf("Expected VoteSet.Add to succeed")
  225. }
  226. }
  227. // val0 votes again for some block.
  228. {
  229. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  230. added, err := signAddVote(privValidators[0], withBlockHash(vote, cmn.RandBytes(32)), voteSet)
  231. if added || err == nil {
  232. t.Errorf("Expected VoteSet.Add to fail, conflicting vote.")
  233. }
  234. }
  235. // val1 votes on another height
  236. {
  237. vote := withValidator(voteProto, privValidators[1].GetAddress(), 1)
  238. added, err := signAddVote(privValidators[1], withHeight(vote, height+1), voteSet)
  239. if added || err == nil {
  240. t.Errorf("Expected VoteSet.Add to fail, wrong height")
  241. }
  242. }
  243. // val2 votes on another round
  244. {
  245. vote := withValidator(voteProto, privValidators[2].GetAddress(), 2)
  246. added, err := signAddVote(privValidators[2], withRound(vote, round+1), voteSet)
  247. if added || err == nil {
  248. t.Errorf("Expected VoteSet.Add to fail, wrong round")
  249. }
  250. }
  251. // val3 votes of another type.
  252. {
  253. vote := withValidator(voteProto, privValidators[3].GetAddress(), 3)
  254. added, err := signAddVote(privValidators[3], withType(vote, VoteTypePrecommit), voteSet)
  255. if added || err == nil {
  256. t.Errorf("Expected VoteSet.Add to fail, wrong type")
  257. }
  258. }
  259. }
  260. func TestConflicts(t *testing.T) {
  261. height, round := 1, 0
  262. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrevote, 4, 1)
  263. blockHash1 := cmn.RandBytes(32)
  264. blockHash2 := cmn.RandBytes(32)
  265. voteProto := &Vote{
  266. ValidatorAddress: nil,
  267. ValidatorIndex: -1,
  268. Height: height,
  269. Round: round,
  270. Type: VoteTypePrevote,
  271. BlockID: BlockID{nil, PartSetHeader{}},
  272. }
  273. // val0 votes for nil.
  274. {
  275. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  276. added, err := signAddVote(privValidators[0], vote, voteSet)
  277. if !added || err != nil {
  278. t.Errorf("Expected VoteSet.Add to succeed")
  279. }
  280. }
  281. // val0 votes again for blockHash1.
  282. {
  283. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  284. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet)
  285. if added {
  286. t.Errorf("Expected VoteSet.Add to fail, conflicting vote.")
  287. }
  288. if err == nil {
  289. t.Errorf("Expected VoteSet.Add to return error, conflicting vote.")
  290. }
  291. }
  292. // start tracking blockHash1
  293. voteSet.SetPeerMaj23("peerA", BlockID{blockHash1, PartSetHeader{}})
  294. // val0 votes again for blockHash1.
  295. {
  296. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  297. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet)
  298. if !added {
  299. t.Errorf("Expected VoteSet.Add to succeed, called SetPeerMaj23().")
  300. }
  301. if err == nil {
  302. t.Errorf("Expected VoteSet.Add to return error, conflicting vote.")
  303. }
  304. }
  305. // attempt tracking blockHash2, should fail because already set for peerA.
  306. voteSet.SetPeerMaj23("peerA", BlockID{blockHash2, PartSetHeader{}})
  307. // val0 votes again for blockHash1.
  308. {
  309. vote := withValidator(voteProto, privValidators[0].GetAddress(), 0)
  310. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash2), voteSet)
  311. if added {
  312. t.Errorf("Expected VoteSet.Add to fail, duplicate SetPeerMaj23() from peerA")
  313. }
  314. if err == nil {
  315. t.Errorf("Expected VoteSet.Add to return error, conflicting vote.")
  316. }
  317. }
  318. // val1 votes for blockHash1.
  319. {
  320. vote := withValidator(voteProto, privValidators[1].GetAddress(), 1)
  321. added, err := signAddVote(privValidators[1], withBlockHash(vote, blockHash1), voteSet)
  322. if !added || err != nil {
  323. t.Errorf("Expected VoteSet.Add to succeed")
  324. }
  325. }
  326. // check
  327. if voteSet.HasTwoThirdsMajority() {
  328. t.Errorf("We shouldn't have 2/3 majority yet")
  329. }
  330. if voteSet.HasTwoThirdsAny() {
  331. t.Errorf("We shouldn't have 2/3 if any votes yet")
  332. }
  333. // val2 votes for blockHash2.
  334. {
  335. vote := withValidator(voteProto, privValidators[2].GetAddress(), 2)
  336. added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash2), voteSet)
  337. if !added || err != nil {
  338. t.Errorf("Expected VoteSet.Add to succeed")
  339. }
  340. }
  341. // check
  342. if voteSet.HasTwoThirdsMajority() {
  343. t.Errorf("We shouldn't have 2/3 majority yet")
  344. }
  345. if !voteSet.HasTwoThirdsAny() {
  346. t.Errorf("We should have 2/3 if any votes")
  347. }
  348. // now attempt tracking blockHash1
  349. voteSet.SetPeerMaj23("peerB", BlockID{blockHash1, PartSetHeader{}})
  350. // val2 votes for blockHash1.
  351. {
  352. vote := withValidator(voteProto, privValidators[2].GetAddress(), 2)
  353. added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash1), voteSet)
  354. if !added {
  355. t.Errorf("Expected VoteSet.Add to succeed")
  356. }
  357. if err == nil {
  358. t.Errorf("Expected VoteSet.Add to return error, conflicting vote")
  359. }
  360. }
  361. // check
  362. if !voteSet.HasTwoThirdsMajority() {
  363. t.Errorf("We should have 2/3 majority for blockHash1")
  364. }
  365. blockIDMaj23, _ := voteSet.TwoThirdsMajority()
  366. if !bytes.Equal(blockIDMaj23.Hash, blockHash1) {
  367. t.Errorf("Got the wrong 2/3 majority blockhash")
  368. }
  369. if !voteSet.HasTwoThirdsAny() {
  370. t.Errorf("We should have 2/3 if any votes")
  371. }
  372. }
  373. func TestMakeCommit(t *testing.T) {
  374. height, round := 1, 0
  375. voteSet, _, privValidators := randVoteSet(height, round, VoteTypePrecommit, 10, 1)
  376. blockHash, blockPartsHeader := crypto.CRandBytes(32), PartSetHeader{123, crypto.CRandBytes(32)}
  377. voteProto := &Vote{
  378. ValidatorAddress: nil,
  379. ValidatorIndex: -1,
  380. Height: height,
  381. Round: round,
  382. Type: VoteTypePrecommit,
  383. BlockID: BlockID{blockHash, blockPartsHeader},
  384. }
  385. // 6 out of 10 voted for some block.
  386. for i := 0; i < 6; i++ {
  387. vote := withValidator(voteProto, privValidators[i].GetAddress(), i)
  388. signAddVote(privValidators[i], vote, voteSet)
  389. }
  390. // MakeCommit should fail.
  391. tst.AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() })
  392. // 7th voted for some other block.
  393. {
  394. vote := withValidator(voteProto, privValidators[6].GetAddress(), 6)
  395. vote = withBlockHash(vote, cmn.RandBytes(32))
  396. vote = withBlockPartsHeader(vote, PartSetHeader{123, cmn.RandBytes(32)})
  397. signAddVote(privValidators[6], vote, voteSet)
  398. }
  399. // The 8th voted like everyone else.
  400. {
  401. vote := withValidator(voteProto, privValidators[7].GetAddress(), 7)
  402. signAddVote(privValidators[7], vote, voteSet)
  403. }
  404. commit := voteSet.MakeCommit()
  405. // Commit should have 10 elements
  406. if len(commit.Precommits) != 10 {
  407. t.Errorf("Commit Precommits should have the same number of precommits as validators")
  408. }
  409. // Ensure that Commit precommits are ordered.
  410. if err := commit.ValidateBasic(); err != nil {
  411. t.Errorf("Error in Commit.ValidateBasic(): %v", err)
  412. }
  413. }