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.

597 lines
16 KiB

lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
lint: Enable Golint (#4212) * Fix many golint errors * Fix golint errors in the 'lite' package * Don't export Pool.store * Fix typo * Revert unwanted changes * Fix errors in counter package * Fix linter errors in kvstore package * Fix linter error in example package * Fix error in tests package * Fix linter errors in v2 package * Fix linter errors in consensus package * Fix linter errors in evidence package * Fix linter error in fail package * Fix linter errors in query package * Fix linter errors in core package * Fix linter errors in node package * Fix linter errors in mempool package * Fix linter error in conn package * Fix linter errors in pex package * Rename PEXReactor export to Reactor * Fix linter errors in trust package * Fix linter errors in upnp package * Fix linter errors in p2p package * Fix linter errors in proxy package * Fix linter errors in mock_test package * Fix linter error in client_test package * Fix linter errors in coretypes package * Fix linter errors in coregrpc package * Fix linter errors in rpcserver package * Fix linter errors in rpctypes package * Fix linter errors in rpctest package * Fix linter error in json2wal script * Fix linter error in wal2json script * Fix linter errors in kv package * Fix linter error in state package * Fix linter error in grpc_client * Fix linter errors in types package * Fix linter error in version package * Fix remaining errors * Address review comments * Fix broken tests * Reconcile package coregrpc * Fix golangci bot error * Fix new golint errors * Fix broken reference * Enable golint linter * minor changes to bring golint into line * fix failing test * fix pex reactor naming * address PR comments
5 years ago
  1. package types
  2. import (
  3. "bytes"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. "github.com/tendermint/tendermint/crypto"
  8. tmrand "github.com/tendermint/tendermint/libs/rand"
  9. tmtime "github.com/tendermint/tendermint/types/time"
  10. )
  11. // NOTE: privValidators are in order
  12. func randVoteSet(
  13. height int64,
  14. round int,
  15. signedMsgType SignedMsgType,
  16. numValidators int,
  17. votingPower int64,
  18. ) (*VoteSet, *ValidatorSet, []PrivValidator) {
  19. valSet, privValidators := RandValidatorSet(numValidators, votingPower)
  20. return NewVoteSet("test_chain_id", height, round, signedMsgType, valSet), valSet, privValidators
  21. }
  22. // Convenience: Return new vote with different validator address/index
  23. func withValidator(vote *Vote, addr []byte, idx int) *Vote {
  24. vote = vote.Copy()
  25. vote.ValidatorAddress = addr
  26. vote.ValidatorIndex = idx
  27. return vote
  28. }
  29. // Convenience: Return new vote with different height
  30. func withHeight(vote *Vote, height int64) *Vote {
  31. vote = vote.Copy()
  32. vote.Height = height
  33. return vote
  34. }
  35. // Convenience: Return new vote with different round
  36. func withRound(vote *Vote, round int) *Vote {
  37. vote = vote.Copy()
  38. vote.Round = round
  39. return vote
  40. }
  41. // Convenience: Return new vote with different type
  42. func withType(vote *Vote, signedMsgType byte) *Vote {
  43. vote = vote.Copy()
  44. vote.Type = SignedMsgType(signedMsgType)
  45. return vote
  46. }
  47. // Convenience: Return new vote with different blockHash
  48. func withBlockHash(vote *Vote, blockHash []byte) *Vote {
  49. vote = vote.Copy()
  50. vote.BlockID.Hash = blockHash
  51. return vote
  52. }
  53. // Convenience: Return new vote with different blockParts
  54. func withBlockPartsHeader(vote *Vote, blockPartsHeader PartSetHeader) *Vote {
  55. vote = vote.Copy()
  56. vote.BlockID.PartsHeader = blockPartsHeader
  57. return vote
  58. }
  59. func TestAddVote(t *testing.T) {
  60. height, round := int64(1), 0
  61. voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1)
  62. val0 := privValidators[0]
  63. // t.Logf(">> %v", voteSet)
  64. val0p, err := val0.GetPubKey()
  65. require.NoError(t, err)
  66. val0Addr := val0p.Address()
  67. if voteSet.GetByAddress(val0Addr) != nil {
  68. t.Errorf("expected GetByAddress(val0.Address) to be nil")
  69. }
  70. if voteSet.BitArray().GetIndex(0) {
  71. t.Errorf("expected BitArray.GetIndex(0) to be false")
  72. }
  73. blockID, ok := voteSet.TwoThirdsMajority()
  74. if ok || !blockID.IsZero() {
  75. t.Errorf("there should be no 2/3 majority")
  76. }
  77. vote := &Vote{
  78. ValidatorAddress: val0Addr,
  79. ValidatorIndex: 0, // since privValidators are in order
  80. Height: height,
  81. Round: round,
  82. Type: PrevoteType,
  83. Timestamp: tmtime.Now(),
  84. BlockID: BlockID{nil, PartSetHeader{}},
  85. }
  86. _, err = signAddVote(val0, vote, voteSet)
  87. if err != nil {
  88. t.Error(err)
  89. }
  90. if voteSet.GetByAddress(val0Addr) == nil {
  91. t.Errorf("expected GetByAddress(val0.Address) to be present")
  92. }
  93. if !voteSet.BitArray().GetIndex(0) {
  94. t.Errorf("expected BitArray.GetIndex(0) to be true")
  95. }
  96. blockID, ok = voteSet.TwoThirdsMajority()
  97. if ok || !blockID.IsZero() {
  98. t.Errorf("there should be no 2/3 majority")
  99. }
  100. }
  101. func Test2_3Majority(t *testing.T) {
  102. height, round := int64(1), 0
  103. voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1)
  104. voteProto := &Vote{
  105. ValidatorAddress: nil, // NOTE: must fill in
  106. ValidatorIndex: -1, // NOTE: must fill in
  107. Height: height,
  108. Round: round,
  109. Type: PrevoteType,
  110. Timestamp: tmtime.Now(),
  111. BlockID: BlockID{nil, PartSetHeader{}},
  112. }
  113. // 6 out of 10 voted for nil.
  114. for i := 0; i < 6; i++ {
  115. pubKey, err := privValidators[i].GetPubKey()
  116. require.NoError(t, err)
  117. addr := pubKey.Address()
  118. vote := withValidator(voteProto, addr, i)
  119. _, err = signAddVote(privValidators[i], vote, voteSet)
  120. if err != nil {
  121. t.Error(err)
  122. }
  123. }
  124. blockID, ok := voteSet.TwoThirdsMajority()
  125. if ok || !blockID.IsZero() {
  126. t.Errorf("there should be no 2/3 majority")
  127. }
  128. // 7th validator voted for some blockhash
  129. {
  130. pubKey, err := privValidators[6].GetPubKey()
  131. require.NoError(t, err)
  132. addr := pubKey.Address()
  133. vote := withValidator(voteProto, addr, 6)
  134. _, err = signAddVote(privValidators[6], withBlockHash(vote, tmrand.Bytes(32)), 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 no 2/3 majority")
  141. }
  142. }
  143. // 8th validator voted for nil.
  144. {
  145. pubKey, err := privValidators[7].GetPubKey()
  146. require.NoError(t, err)
  147. addr := pubKey.Address()
  148. vote := withValidator(voteProto, addr, 7)
  149. _, err = signAddVote(privValidators[7], vote, voteSet)
  150. if err != nil {
  151. t.Error(err)
  152. }
  153. blockID, ok = voteSet.TwoThirdsMajority()
  154. if !ok || !blockID.IsZero() {
  155. t.Errorf("there should be 2/3 majority for nil")
  156. }
  157. }
  158. }
  159. func Test2_3MajorityRedux(t *testing.T) {
  160. height, round := int64(1), 0
  161. voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 100, 1)
  162. blockHash := crypto.CRandBytes(32)
  163. blockPartsTotal := 123
  164. blockPartsHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}
  165. voteProto := &Vote{
  166. ValidatorAddress: nil, // NOTE: must fill in
  167. ValidatorIndex: -1, // NOTE: must fill in
  168. Height: height,
  169. Round: round,
  170. Timestamp: tmtime.Now(),
  171. Type: PrevoteType,
  172. BlockID: BlockID{blockHash, blockPartsHeader},
  173. }
  174. // 66 out of 100 voted for nil.
  175. for i := 0; i < 66; i++ {
  176. pubKey, err := privValidators[i].GetPubKey()
  177. require.NoError(t, err)
  178. addr := pubKey.Address()
  179. vote := withValidator(voteProto, addr, i)
  180. _, err = signAddVote(privValidators[i], vote, voteSet)
  181. if err != nil {
  182. t.Error(err)
  183. }
  184. }
  185. blockID, ok := voteSet.TwoThirdsMajority()
  186. if ok || !blockID.IsZero() {
  187. t.Errorf("there should be no 2/3 majority")
  188. }
  189. // 67th validator voted for nil
  190. {
  191. pubKey, err := privValidators[66].GetPubKey()
  192. require.NoError(t, err)
  193. adrr := pubKey.Address()
  194. vote := withValidator(voteProto, adrr, 66)
  195. _, err = signAddVote(privValidators[66], withBlockHash(vote, nil), voteSet)
  196. if err != nil {
  197. t.Error(err)
  198. }
  199. blockID, ok = voteSet.TwoThirdsMajority()
  200. if ok || !blockID.IsZero() {
  201. t.Errorf("there should be no 2/3 majority: last vote added was nil")
  202. }
  203. }
  204. // 68th validator voted for a different BlockParts PartSetHeader
  205. {
  206. pubKey, err := privValidators[67].GetPubKey()
  207. require.NoError(t, err)
  208. addr := pubKey.Address()
  209. vote := withValidator(voteProto, addr, 67)
  210. blockPartsHeader := PartSetHeader{blockPartsTotal, crypto.CRandBytes(32)}
  211. _, err = signAddVote(privValidators[67], withBlockPartsHeader(vote, blockPartsHeader), voteSet)
  212. if err != nil {
  213. t.Error(err)
  214. }
  215. blockID, ok = voteSet.TwoThirdsMajority()
  216. if ok || !blockID.IsZero() {
  217. t.Errorf("there should be no 2/3 majority: last vote added had different PartSetHeader Hash")
  218. }
  219. }
  220. // 69th validator voted for different BlockParts Total
  221. {
  222. pubKey, err := privValidators[68].GetPubKey()
  223. require.NoError(t, err)
  224. addr := pubKey.Address()
  225. vote := withValidator(voteProto, addr, 68)
  226. blockPartsHeader := PartSetHeader{blockPartsTotal + 1, blockPartsHeader.Hash}
  227. _, err = signAddVote(privValidators[68], withBlockPartsHeader(vote, blockPartsHeader), voteSet)
  228. if err != nil {
  229. t.Error(err)
  230. }
  231. blockID, ok = voteSet.TwoThirdsMajority()
  232. if ok || !blockID.IsZero() {
  233. t.Errorf("there should be no 2/3 majority: last vote added had different PartSetHeader Total")
  234. }
  235. }
  236. // 70th validator voted for different BlockHash
  237. {
  238. pubKey, err := privValidators[69].GetPubKey()
  239. require.NoError(t, err)
  240. addr := pubKey.Address()
  241. vote := withValidator(voteProto, addr, 69)
  242. _, err = signAddVote(privValidators[69], withBlockHash(vote, tmrand.Bytes(32)), voteSet)
  243. if err != nil {
  244. t.Error(err)
  245. }
  246. blockID, ok = voteSet.TwoThirdsMajority()
  247. if ok || !blockID.IsZero() {
  248. t.Errorf("there should be no 2/3 majority: last vote added had different BlockHash")
  249. }
  250. }
  251. // 71st validator voted for the right BlockHash & BlockPartsHeader
  252. {
  253. pubKey, err := privValidators[70].GetPubKey()
  254. require.NoError(t, err)
  255. addr := pubKey.Address()
  256. vote := withValidator(voteProto, addr, 70)
  257. _, err = signAddVote(privValidators[70], vote, voteSet)
  258. if err != nil {
  259. t.Error(err)
  260. }
  261. blockID, ok = voteSet.TwoThirdsMajority()
  262. if !ok || !blockID.Equals(BlockID{blockHash, blockPartsHeader}) {
  263. t.Errorf("there should be 2/3 majority")
  264. }
  265. }
  266. }
  267. func TestBadVotes(t *testing.T) {
  268. height, round := int64(1), 0
  269. voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 10, 1)
  270. voteProto := &Vote{
  271. ValidatorAddress: nil,
  272. ValidatorIndex: -1,
  273. Height: height,
  274. Round: round,
  275. Timestamp: tmtime.Now(),
  276. Type: PrevoteType,
  277. BlockID: BlockID{nil, PartSetHeader{}},
  278. }
  279. // val0 votes for nil.
  280. {
  281. pubKey, err := privValidators[0].GetPubKey()
  282. require.NoError(t, err)
  283. addr := pubKey.Address()
  284. vote := withValidator(voteProto, addr, 0)
  285. added, err := signAddVote(privValidators[0], vote, voteSet)
  286. if !added || err != nil {
  287. t.Errorf("expected VoteSet.Add to succeed")
  288. }
  289. }
  290. // val0 votes again for some block.
  291. {
  292. pubKey, err := privValidators[0].GetPubKey()
  293. require.NoError(t, err)
  294. addr := pubKey.Address()
  295. vote := withValidator(voteProto, addr, 0)
  296. added, err := signAddVote(privValidators[0], withBlockHash(vote, tmrand.Bytes(32)), voteSet)
  297. if added || err == nil {
  298. t.Errorf("expected VoteSet.Add to fail, conflicting vote.")
  299. }
  300. }
  301. // val1 votes on another height
  302. {
  303. pubKey, err := privValidators[1].GetPubKey()
  304. require.NoError(t, err)
  305. addr := pubKey.Address()
  306. vote := withValidator(voteProto, addr, 1)
  307. added, err := signAddVote(privValidators[1], withHeight(vote, height+1), voteSet)
  308. if added || err == nil {
  309. t.Errorf("expected VoteSet.Add to fail, wrong height")
  310. }
  311. }
  312. // val2 votes on another round
  313. {
  314. pubKey, err := privValidators[2].GetPubKey()
  315. require.NoError(t, err)
  316. addr := pubKey.Address()
  317. vote := withValidator(voteProto, addr, 2)
  318. added, err := signAddVote(privValidators[2], withRound(vote, round+1), voteSet)
  319. if added || err == nil {
  320. t.Errorf("expected VoteSet.Add to fail, wrong round")
  321. }
  322. }
  323. // val3 votes of another type.
  324. {
  325. pubKey, err := privValidators[3].GetPubKey()
  326. require.NoError(t, err)
  327. addr := pubKey.Address()
  328. vote := withValidator(voteProto, addr, 3)
  329. added, err := signAddVote(privValidators[3], withType(vote, byte(PrecommitType)), voteSet)
  330. if added || err == nil {
  331. t.Errorf("expected VoteSet.Add to fail, wrong type")
  332. }
  333. }
  334. }
  335. func TestConflicts(t *testing.T) {
  336. height, round := int64(1), 0
  337. voteSet, _, privValidators := randVoteSet(height, round, PrevoteType, 4, 1)
  338. blockHash1 := tmrand.Bytes(32)
  339. blockHash2 := tmrand.Bytes(32)
  340. voteProto := &Vote{
  341. ValidatorAddress: nil,
  342. ValidatorIndex: -1,
  343. Height: height,
  344. Round: round,
  345. Timestamp: tmtime.Now(),
  346. Type: PrevoteType,
  347. BlockID: BlockID{nil, PartSetHeader{}},
  348. }
  349. val0, err := privValidators[0].GetPubKey()
  350. require.NoError(t, err)
  351. val0Addr := val0.Address()
  352. // val0 votes for nil.
  353. {
  354. vote := withValidator(voteProto, val0Addr, 0)
  355. added, err := signAddVote(privValidators[0], vote, voteSet)
  356. if !added || err != nil {
  357. t.Errorf("expected VoteSet.Add to succeed")
  358. }
  359. }
  360. // val0 votes again for blockHash1.
  361. {
  362. vote := withValidator(voteProto, val0Addr, 0)
  363. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet)
  364. if added {
  365. t.Errorf("expected VoteSet.Add to fail, conflicting vote.")
  366. }
  367. if err == nil {
  368. t.Errorf("expected VoteSet.Add to return error, conflicting vote.")
  369. }
  370. }
  371. // start tracking blockHash1
  372. voteSet.SetPeerMaj23("peerA", BlockID{blockHash1, PartSetHeader{}})
  373. // val0 votes again for blockHash1.
  374. {
  375. vote := withValidator(voteProto, val0Addr, 0)
  376. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash1), voteSet)
  377. if !added {
  378. t.Errorf("expected VoteSet.Add to succeed, called SetPeerMaj23().")
  379. }
  380. if err == nil {
  381. t.Errorf("expected VoteSet.Add to return error, conflicting vote.")
  382. }
  383. }
  384. // attempt tracking blockHash2, should fail because already set for peerA.
  385. voteSet.SetPeerMaj23("peerA", BlockID{blockHash2, PartSetHeader{}})
  386. // val0 votes again for blockHash1.
  387. {
  388. vote := withValidator(voteProto, val0Addr, 0)
  389. added, err := signAddVote(privValidators[0], withBlockHash(vote, blockHash2), voteSet)
  390. if added {
  391. t.Errorf("expected VoteSet.Add to fail, duplicate SetPeerMaj23() from peerA")
  392. }
  393. if err == nil {
  394. t.Errorf("expected VoteSet.Add to return error, conflicting vote.")
  395. }
  396. }
  397. // val1 votes for blockHash1.
  398. {
  399. pv, err := privValidators[1].GetPubKey()
  400. assert.NoError(t, err)
  401. addr := pv.Address()
  402. vote := withValidator(voteProto, addr, 1)
  403. added, err := signAddVote(privValidators[1], withBlockHash(vote, blockHash1), voteSet)
  404. if !added || err != nil {
  405. t.Errorf("expected VoteSet.Add to succeed")
  406. }
  407. }
  408. // check
  409. if voteSet.HasTwoThirdsMajority() {
  410. t.Errorf("we shouldn't have 2/3 majority yet")
  411. }
  412. if voteSet.HasTwoThirdsAny() {
  413. t.Errorf("we shouldn't have 2/3 if any votes yet")
  414. }
  415. // val2 votes for blockHash2.
  416. {
  417. pv, err := privValidators[2].GetPubKey()
  418. assert.NoError(t, err)
  419. addr := pv.Address()
  420. vote := withValidator(voteProto, addr, 2)
  421. added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash2), voteSet)
  422. if !added || err != nil {
  423. t.Errorf("expected VoteSet.Add to succeed")
  424. }
  425. }
  426. // check
  427. if voteSet.HasTwoThirdsMajority() {
  428. t.Errorf("we shouldn't have 2/3 majority yet")
  429. }
  430. if !voteSet.HasTwoThirdsAny() {
  431. t.Errorf("we should have 2/3 if any votes")
  432. }
  433. // now attempt tracking blockHash1
  434. voteSet.SetPeerMaj23("peerB", BlockID{blockHash1, PartSetHeader{}})
  435. // val2 votes for blockHash1.
  436. {
  437. pv, err := privValidators[2].GetPubKey()
  438. assert.NoError(t, err)
  439. addr := pv.Address()
  440. vote := withValidator(voteProto, addr, 2)
  441. added, err := signAddVote(privValidators[2], withBlockHash(vote, blockHash1), voteSet)
  442. if !added {
  443. t.Errorf("expected VoteSet.Add to succeed")
  444. }
  445. if err == nil {
  446. t.Errorf("expected VoteSet.Add to return error, conflicting vote")
  447. }
  448. }
  449. // check
  450. if !voteSet.HasTwoThirdsMajority() {
  451. t.Errorf("we should have 2/3 majority for blockHash1")
  452. }
  453. blockIDMaj23, _ := voteSet.TwoThirdsMajority()
  454. if !bytes.Equal(blockIDMaj23.Hash, blockHash1) {
  455. t.Errorf("got the wrong 2/3 majority blockhash")
  456. }
  457. if !voteSet.HasTwoThirdsAny() {
  458. t.Errorf("we should have 2/3 if any votes")
  459. }
  460. }
  461. func TestMakeCommit(t *testing.T) {
  462. height, round := int64(1), 0
  463. voteSet, _, privValidators := randVoteSet(height, round, PrecommitType, 10, 1)
  464. blockHash, blockPartsHeader := crypto.CRandBytes(32), PartSetHeader{123, crypto.CRandBytes(32)}
  465. voteProto := &Vote{
  466. ValidatorAddress: nil,
  467. ValidatorIndex: -1,
  468. Height: height,
  469. Round: round,
  470. Timestamp: tmtime.Now(),
  471. Type: PrecommitType,
  472. BlockID: BlockID{blockHash, blockPartsHeader},
  473. }
  474. // 6 out of 10 voted for some block.
  475. for i := 0; i < 6; i++ {
  476. pv, err := privValidators[i].GetPubKey()
  477. assert.NoError(t, err)
  478. addr := pv.Address()
  479. vote := withValidator(voteProto, addr, i)
  480. _, err = signAddVote(privValidators[i], vote, voteSet)
  481. if err != nil {
  482. t.Error(err)
  483. }
  484. }
  485. // MakeCommit should fail.
  486. assert.Panics(t, func() { voteSet.MakeCommit() }, "Doesn't have +2/3 majority")
  487. // 7th voted for some other block.
  488. {
  489. pv, err := privValidators[6].GetPubKey()
  490. assert.NoError(t, err)
  491. addr := pv.Address()
  492. vote := withValidator(voteProto, addr, 6)
  493. vote = withBlockHash(vote, tmrand.Bytes(32))
  494. vote = withBlockPartsHeader(vote, PartSetHeader{123, tmrand.Bytes(32)})
  495. _, err = signAddVote(privValidators[6], vote, voteSet)
  496. if err != nil {
  497. t.Error(err)
  498. }
  499. }
  500. // The 8th voted like everyone else.
  501. {
  502. pv, err := privValidators[7].GetPubKey()
  503. assert.NoError(t, err)
  504. addr := pv.Address()
  505. vote := withValidator(voteProto, addr, 7)
  506. _, err = signAddVote(privValidators[7], vote, voteSet)
  507. if err != nil {
  508. t.Error(err)
  509. }
  510. }
  511. // The 9th voted for nil.
  512. {
  513. pv, err := privValidators[8].GetPubKey()
  514. assert.NoError(t, err)
  515. addr := pv.Address()
  516. vote := withValidator(voteProto, addr, 8)
  517. vote.BlockID = BlockID{}
  518. _, err = signAddVote(privValidators[8], vote, voteSet)
  519. if err != nil {
  520. t.Error(err)
  521. }
  522. }
  523. commit := voteSet.MakeCommit()
  524. // Commit should have 10 elements
  525. if len(commit.Signatures) != 10 {
  526. t.Errorf("expected commit to include %d elems, got %d", 10, len(commit.Signatures))
  527. }
  528. // Ensure that Commit is good.
  529. if err := commit.ValidateBasic(); err != nil {
  530. t.Errorf("error in Commit.ValidateBasic(): %v", err)
  531. }
  532. }