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.

530 lines
15 KiB

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