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.

508 lines
15 KiB

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