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.

470 lines
14 KiB

pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
6 years ago
pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
6 years ago
  1. package state
  2. import (
  3. "context"
  4. "fmt"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. "github.com/tendermint/tendermint/abci/example/kvstore"
  10. abci "github.com/tendermint/tendermint/abci/types"
  11. "github.com/tendermint/tendermint/crypto/ed25519"
  12. "github.com/tendermint/tendermint/crypto/secp256k1"
  13. cmn "github.com/tendermint/tendermint/libs/common"
  14. dbm "github.com/tendermint/tendermint/libs/db"
  15. "github.com/tendermint/tendermint/libs/log"
  16. tmtime "github.com/tendermint/tendermint/types/time"
  17. "github.com/tendermint/tendermint/proxy"
  18. "github.com/tendermint/tendermint/types"
  19. )
  20. var (
  21. chainID = "execution_chain"
  22. testPartSize = 65536
  23. nTxsPerBlock = 10
  24. )
  25. func TestApplyBlock(t *testing.T) {
  26. cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication())
  27. proxyApp := proxy.NewAppConns(cc)
  28. err := proxyApp.Start()
  29. require.Nil(t, err)
  30. defer proxyApp.Stop()
  31. state, stateDB := state(1, 1)
  32. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
  33. MockMempool{}, MockEvidencePool{})
  34. block := makeBlock(state, 1)
  35. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  36. state, err = blockExec.ApplyBlock(state, blockID, block)
  37. require.Nil(t, err)
  38. // TODO check state and mempool
  39. }
  40. // TestBeginBlockValidators ensures we send absent validators list.
  41. func TestBeginBlockValidators(t *testing.T) {
  42. app := &testApp{}
  43. cc := proxy.NewLocalClientCreator(app)
  44. proxyApp := proxy.NewAppConns(cc)
  45. err := proxyApp.Start()
  46. require.Nil(t, err)
  47. defer proxyApp.Stop()
  48. state, stateDB := state(2, 2)
  49. prevHash := state.LastBlockID.Hash
  50. prevParts := types.PartSetHeader{}
  51. prevBlockID := types.BlockID{prevHash, prevParts}
  52. now := tmtime.Now()
  53. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  54. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  55. testCases := []struct {
  56. desc string
  57. lastCommitPrecommits []*types.CommitSig
  58. expectedAbsentValidators []int
  59. }{
  60. {"none absent", []*types.CommitSig{commitSig0, commitSig1}, []int{}},
  61. {"one absent", []*types.CommitSig{commitSig0, nil}, []int{1}},
  62. {"multiple absent", []*types.CommitSig{nil, nil}, []int{0, 1}},
  63. }
  64. for _, tc := range testCases {
  65. lastCommit := types.NewCommit(prevBlockID, tc.lastCommitPrecommits)
  66. // block for height 2
  67. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  68. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
  69. require.Nil(t, err, tc.desc)
  70. // -> app receives a list of validators with a bool indicating if they signed
  71. ctr := 0
  72. for i, v := range app.CommitVotes {
  73. if ctr < len(tc.expectedAbsentValidators) &&
  74. tc.expectedAbsentValidators[ctr] == i {
  75. assert.False(t, v.SignedLastBlock)
  76. ctr++
  77. } else {
  78. assert.True(t, v.SignedLastBlock)
  79. }
  80. }
  81. }
  82. }
  83. // TestBeginBlockByzantineValidators ensures we send byzantine validators list.
  84. func TestBeginBlockByzantineValidators(t *testing.T) {
  85. app := &testApp{}
  86. cc := proxy.NewLocalClientCreator(app)
  87. proxyApp := proxy.NewAppConns(cc)
  88. err := proxyApp.Start()
  89. require.Nil(t, err)
  90. defer proxyApp.Stop()
  91. state, stateDB := state(2, 12)
  92. prevHash := state.LastBlockID.Hash
  93. prevParts := types.PartSetHeader{}
  94. prevBlockID := types.BlockID{prevHash, prevParts}
  95. height1, idx1, val1 := int64(8), 0, state.Validators.Validators[0].Address
  96. height2, idx2, val2 := int64(3), 1, state.Validators.Validators[1].Address
  97. ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
  98. ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
  99. now := tmtime.Now()
  100. valSet := state.Validators
  101. testCases := []struct {
  102. desc string
  103. evidence []types.Evidence
  104. expectedByzantineValidators []abci.Evidence
  105. }{
  106. {"none byzantine", []types.Evidence{}, []abci.Evidence{}},
  107. {"one byzantine", []types.Evidence{ev1}, []abci.Evidence{types.TM2PB.Evidence(ev1, valSet, now)}},
  108. {"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
  109. types.TM2PB.Evidence(ev1, valSet, now),
  110. types.TM2PB.Evidence(ev2, valSet, now)}},
  111. }
  112. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  113. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  114. commitSigs := []*types.CommitSig{commitSig0, commitSig1}
  115. lastCommit := types.NewCommit(prevBlockID, commitSigs)
  116. for _, tc := range testCases {
  117. block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  118. block.Time = now
  119. block.Evidence.Evidence = tc.evidence
  120. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
  121. require.Nil(t, err, tc.desc)
  122. // -> app must receive an index of the byzantine validator
  123. assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
  124. }
  125. }
  126. func TestValidateValidatorUpdates(t *testing.T) {
  127. pubkey1 := ed25519.GenPrivKey().PubKey()
  128. pubkey2 := ed25519.GenPrivKey().PubKey()
  129. secpKey := secp256k1.GenPrivKey().PubKey()
  130. defaultValidatorParams := types.ValidatorParams{[]string{types.ABCIPubKeyTypeEd25519}}
  131. testCases := []struct {
  132. name string
  133. abciUpdates []abci.ValidatorUpdate
  134. validatorParams types.ValidatorParams
  135. shouldErr bool
  136. }{
  137. {
  138. "adding a validator is OK",
  139. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  140. defaultValidatorParams,
  141. false,
  142. },
  143. {
  144. "updating a validator is OK",
  145. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  146. defaultValidatorParams,
  147. false,
  148. },
  149. {
  150. "removing a validator is OK",
  151. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  152. defaultValidatorParams,
  153. false,
  154. },
  155. {
  156. "adding a validator with negative power results in error",
  157. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: -100}},
  158. defaultValidatorParams,
  159. true,
  160. },
  161. {
  162. "adding a validator with pubkey thats not in validator params results in error",
  163. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(secpKey), Power: -100}},
  164. defaultValidatorParams,
  165. true,
  166. },
  167. }
  168. for _, tc := range testCases {
  169. t.Run(tc.name, func(t *testing.T) {
  170. err := validateValidatorUpdates(tc.abciUpdates, tc.validatorParams)
  171. if tc.shouldErr {
  172. assert.Error(t, err)
  173. } else {
  174. assert.NoError(t, err)
  175. }
  176. })
  177. }
  178. }
  179. func TestUpdateValidators(t *testing.T) {
  180. pubkey1 := ed25519.GenPrivKey().PubKey()
  181. val1 := types.NewValidator(pubkey1, 10)
  182. pubkey2 := ed25519.GenPrivKey().PubKey()
  183. val2 := types.NewValidator(pubkey2, 20)
  184. testCases := []struct {
  185. name string
  186. currentSet *types.ValidatorSet
  187. abciUpdates []abci.ValidatorUpdate
  188. resultingSet *types.ValidatorSet
  189. shouldErr bool
  190. }{
  191. {
  192. "adding a validator is OK",
  193. types.NewValidatorSet([]*types.Validator{val1}),
  194. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  195. types.NewValidatorSet([]*types.Validator{val1, val2}),
  196. false,
  197. },
  198. {
  199. "updating a validator is OK",
  200. types.NewValidatorSet([]*types.Validator{val1}),
  201. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  202. types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}),
  203. false,
  204. },
  205. {
  206. "removing a validator is OK",
  207. types.NewValidatorSet([]*types.Validator{val1, val2}),
  208. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  209. types.NewValidatorSet([]*types.Validator{val1}),
  210. false,
  211. },
  212. {
  213. "removing a non-existing validator results in error",
  214. types.NewValidatorSet([]*types.Validator{val1}),
  215. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  216. types.NewValidatorSet([]*types.Validator{val1}),
  217. true,
  218. },
  219. }
  220. for _, tc := range testCases {
  221. t.Run(tc.name, func(t *testing.T) {
  222. updates, err := types.PB2TM.ValidatorUpdates(tc.abciUpdates)
  223. assert.NoError(t, err)
  224. err = tc.currentSet.UpdateWithChangeSet(updates)
  225. if tc.shouldErr {
  226. assert.Error(t, err)
  227. } else {
  228. assert.NoError(t, err)
  229. require.Equal(t, tc.resultingSet.Size(), tc.currentSet.Size())
  230. assert.Equal(t, tc.resultingSet.TotalVotingPower(), tc.currentSet.TotalVotingPower())
  231. assert.Equal(t, tc.resultingSet.Validators[0].Address, tc.currentSet.Validators[0].Address)
  232. if tc.resultingSet.Size() > 1 {
  233. assert.Equal(t, tc.resultingSet.Validators[1].Address, tc.currentSet.Validators[1].Address)
  234. }
  235. }
  236. })
  237. }
  238. }
  239. // TestEndBlockValidatorUpdates ensures we update validator set and send an event.
  240. func TestEndBlockValidatorUpdates(t *testing.T) {
  241. app := &testApp{}
  242. cc := proxy.NewLocalClientCreator(app)
  243. proxyApp := proxy.NewAppConns(cc)
  244. err := proxyApp.Start()
  245. require.Nil(t, err)
  246. defer proxyApp.Stop()
  247. state, stateDB := state(1, 1)
  248. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), MockMempool{}, MockEvidencePool{})
  249. eventBus := types.NewEventBus()
  250. err = eventBus.Start()
  251. require.NoError(t, err)
  252. defer eventBus.Stop()
  253. blockExec.SetEventBus(eventBus)
  254. updatesSub, err := eventBus.Subscribe(context.Background(), "TestEndBlockValidatorUpdates", types.EventQueryValidatorSetUpdates)
  255. require.NoError(t, err)
  256. block := makeBlock(state, 1)
  257. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  258. pubkey := ed25519.GenPrivKey().PubKey()
  259. app.ValidatorUpdates = []abci.ValidatorUpdate{
  260. {PubKey: types.TM2PB.PubKey(pubkey), Power: 10},
  261. }
  262. state, err = blockExec.ApplyBlock(state, blockID, block)
  263. require.Nil(t, err)
  264. // test new validator was added to NextValidators
  265. if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) {
  266. idx, _ := state.NextValidators.GetByAddress(pubkey.Address())
  267. if idx < 0 {
  268. t.Fatalf("can't find address %v in the set %v", pubkey.Address(), state.NextValidators)
  269. }
  270. }
  271. // test we threw an event
  272. select {
  273. case msg := <-updatesSub.Out():
  274. event, ok := msg.Data().(types.EventDataValidatorSetUpdates)
  275. require.True(t, ok, "Expected event of type EventDataValidatorSetUpdates, got %T", msg.Data())
  276. if assert.NotEmpty(t, event.ValidatorUpdates) {
  277. assert.Equal(t, pubkey, event.ValidatorUpdates[0].PubKey)
  278. assert.EqualValues(t, 10, event.ValidatorUpdates[0].VotingPower)
  279. }
  280. case <-updatesSub.Cancelled():
  281. t.Fatalf("updatesSub was cancelled (reason: %v)", updatesSub.Err())
  282. case <-time.After(1 * time.Second):
  283. t.Fatal("Did not receive EventValidatorSetUpdates within 1 sec.")
  284. }
  285. }
  286. // TestEndBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that
  287. // would result in empty set causes no panic, an error is raised and NextValidators is not updated
  288. func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
  289. app := &testApp{}
  290. cc := proxy.NewLocalClientCreator(app)
  291. proxyApp := proxy.NewAppConns(cc)
  292. err := proxyApp.Start()
  293. require.Nil(t, err)
  294. defer proxyApp.Stop()
  295. state, stateDB := state(1, 1)
  296. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), MockMempool{}, MockEvidencePool{})
  297. block := makeBlock(state, 1)
  298. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  299. // Remove the only validator
  300. app.ValidatorUpdates = []abci.ValidatorUpdate{
  301. {PubKey: types.TM2PB.PubKey(state.Validators.Validators[0].PubKey), Power: 0},
  302. }
  303. assert.NotPanics(t, func() { state, err = blockExec.ApplyBlock(state, blockID, block) })
  304. assert.NotNil(t, err)
  305. assert.NotEmpty(t, state.NextValidators.Validators)
  306. }
  307. //----------------------------------------------------------------------------
  308. // make some bogus txs
  309. func makeTxs(height int64) (txs []types.Tx) {
  310. for i := 0; i < nTxsPerBlock; i++ {
  311. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  312. }
  313. return txs
  314. }
  315. func state(nVals, height int) (State, dbm.DB) {
  316. vals := make([]types.GenesisValidator, nVals)
  317. for i := 0; i < nVals; i++ {
  318. secret := []byte(fmt.Sprintf("test%d", i))
  319. pk := ed25519.GenPrivKeyFromSecret(secret)
  320. vals[i] = types.GenesisValidator{
  321. pk.PubKey().Address(),
  322. pk.PubKey(),
  323. 1000,
  324. fmt.Sprintf("test%d", i),
  325. }
  326. }
  327. s, _ := MakeGenesisState(&types.GenesisDoc{
  328. ChainID: chainID,
  329. Validators: vals,
  330. AppHash: nil,
  331. })
  332. // save validators to db for 2 heights
  333. stateDB := dbm.NewMemDB()
  334. SaveState(stateDB, s)
  335. for i := 1; i < height; i++ {
  336. s.LastBlockHeight++
  337. s.LastValidators = s.Validators.Copy()
  338. SaveState(stateDB, s)
  339. }
  340. return s, stateDB
  341. }
  342. func makeBlock(state State, height int64) *types.Block {
  343. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil, state.Validators.GetProposer().Address)
  344. return block
  345. }
  346. //----------------------------------------------------------------------------
  347. type testApp struct {
  348. abci.BaseApplication
  349. CommitVotes []abci.VoteInfo
  350. ByzantineValidators []abci.Evidence
  351. ValidatorUpdates []abci.ValidatorUpdate
  352. }
  353. var _ abci.Application = (*testApp)(nil)
  354. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  355. return abci.ResponseInfo{}
  356. }
  357. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  358. app.CommitVotes = req.LastCommitInfo.Votes
  359. app.ByzantineValidators = req.ByzantineValidators
  360. return abci.ResponseBeginBlock{}
  361. }
  362. func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
  363. return abci.ResponseEndBlock{ValidatorUpdates: app.ValidatorUpdates}
  364. }
  365. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  366. return abci.ResponseDeliverTx{Tags: []cmn.KVPair{}}
  367. }
  368. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  369. return abci.ResponseCheckTx{}
  370. }
  371. func (app *testApp) Commit() abci.ResponseCommit {
  372. return abci.ResponseCommit{}
  373. }
  374. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  375. return
  376. }